{
  "openapi": "3.1.0",
  "info": {
    "title": "YieldFabric Payment Domain API",
    "version": "1.0.0",
    "summary": "GraphQL + REST API for deals, payments, swaps, obligations, composed operations, and interop.",
    "description": "Canonical specification for the YieldFabric payment domain.\n\n## Public GraphQL surface\n\nCross-subgraph/shared-core reads and auth/agents mutations use\n`https://api.yieldfabric.com/graphql`. Every payments mutation and every\nquery backed by a payments instance's PAY/MQ database or chain RPC uses\npayments-direct: `https://pay.test.yieldfabric.com/graphql` for Test or\n`https://pay.live.yieldfabric.com/graphql` for Live. The selected host must\nmatch the authenticated JWT session.\n\nPayments REST, SSE, WebSocket and message-status calls use that same\nselected Test/Live payments host.\n\n## How to read this spec\n\nThis is an **OpenAPI 3.1 spec with GraphQL extensions**. The only real HTTP\nGraphQL operation is `POST /graphql`; the operation determines whether the\nhost is the federated gateway or JWT-selected payments-direct service.\nPer-operation detail (input schema, output schema, examples, MCP\nmetadata, code samples) lives in `operations/**/*.yaml` files, indexed by\nthe `x-graphql-operations` registry on the `/graphql` path. Tools that walk\nthe registry (the website renderer, the MCP server generator) get one panel\nor one tool per operation; tools that don't (stock Swagger UI) see the\nhonest GraphQL endpoint shape.\n\nSee `README.md` for the full convention reference and `guides/authentication.md`\nfor connection requirements.\n",
    "contact": {
      "name": "YieldFabric Team",
      "email": "support@yieldfabric.com"
    },
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://api.yieldfabric.com",
      "description": "Federated GraphQL gateway"
    },
    {
      "url": "https://pay.test.yieldfabric.com",
      "description": "Test payments-direct GraphQL + REST"
    },
    {
      "url": "https://pay.live.yieldfabric.com",
      "description": "Live payments-direct GraphQL + REST"
    }
  ],
  "tags": [
    {
      "name": "Deals",
      "description": "Deal Management System (DMS). Multi-party deal lifecycle: propose → sign\n→ (auto-)activate, with reject/counter-offer/cancel branches. See\n[deal-lifecycle guide](guides/deal-lifecycle.md).\n",
      "externalDocs": {
        "url": "guides/deal-lifecycle.md",
        "description": "Deal lifecycle guide"
      }
    },
    {
      "name": "Payments",
      "description": "Vault funding (deposit/withdraw), instant sends, accept (single/all),\nMerkle-tree distributions. See [payment-lifecycle guide](guides/payment-lifecycle.md).\n",
      "externalDocs": {
        "url": "guides/payment-lifecycle.md",
        "description": "Payment lifecycle guide"
      }
    },
    {
      "name": "Obligations",
      "description": "Contract creation, acceptance, transfer, cancellation. Cash vs credit\nobligations, oracle-conditioned unlocks, time locks. See [obligation-lifecycle guide](guides/obligation-lifecycle.md).\n",
      "externalDocs": {
        "url": "guides/obligation-lifecycle.md",
        "description": "Obligation lifecycle guide"
      }
    },
    {
      "name": "Swaps",
      "description": "Atomic swaps and repo swaps with collateral. Create, complete, cancel,\nrepurchase, roll, expire-collateral. See [swap-lifecycle guide](guides/swap-lifecycle.md).\n",
      "externalDocs": {
        "url": "guides/swap-lifecycle.md",
        "description": "Swap lifecycle guide"
      }
    },
    {
      "name": "Composed",
      "description": "Atomic batch execution of mixed operations (create + transfer + cancel +\n...) under a single composed-contract id. See [composed-operations guide](guides/composed-operations.md).\n",
      "externalDocs": {
        "url": "guides/composed-operations.md",
        "description": "Composed operations guide"
      }
    },
    {
      "name": "Interop",
      "description": "Cross-service credential exchange (SIWE-authed). Service manifest,\nanchor listing, credential export/import, counterparty fetch. See [interop guide](guides/interop.md).\n",
      "externalDocs": {
        "url": "guides/interop.md",
        "description": "Interop guide"
      }
    },
    {
      "name": "Queries",
      "description": "Read-only queries: payments, contracts, swaps, positions, entities, plus\nthe dealFlow.* family.\n"
    },
    {
      "name": "Messages (REST)",
      "description": "Status, polling, signing, cancellation, and canonical failed-message\nredrive for queued operations. See `paths/messages.yaml`.\n"
    },
    {
      "name": "Sister-service REST",
      "description": "JWT-gated chain reads and MQ submission used by sister services\n(auth, ops tooling). See [authentication guide](guides/authentication.md)\nfor service-token shape.\n"
    },
    {
      "name": "MCP",
      "description": "Model Context Protocol surfaces: the standard `POST /mcp` (JSON-RPC\n2.0, connector credentials only, 14 read-only tools) with its\nOAuth discovery documents, and the bespoke `/api/mcp/*` REST envelope.\nSee `paths/mcp.yaml`.\n"
    }
  ],
  "paths": {
    "/api/events/stream": {
      "get": {
        "operationId": "streamEntityEvents",
        "summary": "Receive live events for the authenticated entity",
        "description": "Connect to the payments host selected by the current JWT chain. Send the\nbearer in the Authorization header (fetch streaming in browser clients).\nThe requested entity must match the authenticated user or delegated group.\nService credentials cannot subscribe. The stream ends at token expiry;\nreconnect with the current token and refresh canonical state after gaps.\nThe legacy query credential remains accepted for installed SDK compatibility.\nA supplied malformed Authorization header never falls back to that credential.\n",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "entity_id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "access_token",
            "in": "query",
            "deprecated": true,
            "description": "Legacy installed-client compatibility only. New clients must use the Authorization header to keep credentials out of URLs.",
            "schema": {
              "type": "string",
              "writeOnly": true
            }
          }
        ],
        "responses": {
          "200": {
            "description": "JSON data events, beginning with Connected; may include Lagged or StreamEnded. Keepalive frames carry no business event.",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired credential, or a rejected subscription context."
          },
          "403": {
            "description": "Requested entity is not the authenticated context, or the caller is a service."
          }
        }
      }
    },
    "/graphql": {
      "post": {
        "operationId": "graphqlEntrypoint",
        "summary": "GraphQL entrypoint for the payment domain",
        "description": "Common GraphQL path for every mutation and query in the payment domain.\nCross-subgraph/shared-core operations use the federated gateway; payments\nmutations and PAY/MQ/RPC-backed reads use the Test/Live payments host that\nmatches the authenticated JWT.\n\nThe request body is the standard GraphQL envelope `{ query, variables, operationName }`.\nThe response is always HTTP 200; per-operation errors come back inside\n`errors[].extensions.code` (see [guides/errors.md](../guides/errors.md)).\n\nWallet-required resolvers fail before side effects with\n`CHAIN_ACCOUNT_REQUIRED` plus entity/chain context. Activate that entity\nthrough auth's chain-account activation resource, refresh the JWT for the\nsame chain, then retry once. Payments never deploys an account implicitly.\n\nTwo session-level refusals are decided before any resolver runs: a\n**connector** session (`session_kind: connector` — an OAuth grant or a\nconnector API key) cannot execute a mutation or subscription\n(`extensions.code: connector_read_only`, `httpStatus: 403`; it proposes\nthrough `POST /mcp` instead), and an RFC 8693 on-behalf-of token minted\nfor another service is refused (`extensions.code: wrong_audience`,\n`httpStatus: 401`). Both are described in\n[guides/errors.md](../guides/errors.md).\n\nFor per-operation detail (input schemas, output schemas, examples, code\nsamples, MCP tool metadata, related operations), see the registry under\n`x-graphql-operations` below and the files in `operations/**/*.yaml`.\n",
        "tags": [
          "Queries",
          "Deals",
          "Payments",
          "Obligations",
          "Swaps",
          "Composed",
          "Interop"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "query"
                ],
                "properties": {
                  "query": {
                    "type": "string",
                    "description": "GraphQL operation source (mutation or query, optionally with fragments)."
                  },
                  "variables": {
                    "type": [
                      "object",
                      "null"
                    ],
                    "additionalProperties": true,
                    "description": "Variable bindings for `$var` references in `query`."
                  },
                  "operationName": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "When `query` declares multiple operations, names the one to execute."
                  }
                },
                "example": {
                  "query": "mutation CreateObligation($input: CreateObligationInput!) {\n  createObligation(input: $input) {\n    success\n    contract_id\n    transaction_id\n  }\n}\n",
                  "variables": {
                    "input": {
                      "counterpart": "alice@yieldfabric",
                      "denomination": "USD",
                      "obligor": "bob@yieldfabric",
                      "expiry": "1735603200"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "GraphQL response (success or error inside `errors[]`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Standard GraphQL response envelope. The HTTP status is always 200; domain\nerrors are inside `errors[]`.\n",
                  "properties": {
                    "data": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "additionalProperties": true,
                      "description": "Per-operation payload. Null when there is an unrecoverable error."
                    },
                    "errors": {
                      "type": [
                        "array",
                        "null"
                      ],
                      "items": {
                        "type": "object",
                        "required": [
                          "message"
                        ],
                        "properties": {
                          "message": {
                            "type": "string"
                          },
                          "path": {
                            "type": "array",
                            "items": {
                              "oneOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "integer"
                                }
                              ]
                            }
                          },
                          "locations": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "line": {
                                  "type": "integer"
                                },
                                "column": {
                                  "type": "integer"
                                }
                              }
                            }
                          },
                          "extensions": {
                            "type": "object",
                            "properties": {
                              "code": {
                                "type": "string",
                                "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                                "enum": [
                                  "BAD_REQUEST",
                                  "UNAUTHORIZED",
                                  "FORBIDDEN",
                                  "CHAIN_ACCOUNT_REQUIRED",
                                  "CHAIN_MODE_MISMATCH",
                                  "NOT_FOUND",
                                  "IDEMPOTENCY_CONFLICT",
                                  "SUBMISSION_OUTCOME_UNKNOWN",
                                  "INSUFFICIENT_BALANCE",
                                  "CONTRACT_STATE_INVALID",
                                  "SWAP_STATE_INVALID",
                                  "DEAL_STATE_INVALID",
                                  "COUNTERPART_NOT_FOUND",
                                  "ORACLE_FAILED",
                                  "SIGNATURE_INVALID",
                                  "DEADLINE_PASSED",
                                  "RATE_LIMITED",
                                  "INTERNAL_ERROR"
                                ]
                              },
                              "httpStatus": {
                                "type": "integer",
                                "description": "HTTP-equivalent status for a GraphQL domain error."
                              },
                              "chainId": {
                                "type": "string",
                                "description": "Selected chain when the error is chain-qualified."
                              },
                              "entityKind": {
                                "type": "string",
                                "enum": [
                                  "user",
                                  "group"
                                ]
                              },
                              "entityId": {
                                "type": "string"
                              },
                              "operation": {
                                "type": "string",
                                "description": "Resolver operation that required the missing account."
                              }
                            },
                            "additionalProperties": true
                          }
                        }
                      }
                    },
                    "extensions": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "additionalProperties": true
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed request or invalid field at the HTTP layer (pre-GraphQL).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "malformed-json": {
                    "summary": "JSON parse error",
                    "value": {
                      "error": {
                        "code": "BAD_REQUEST",
                        "message": "request body is not valid JSON"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, expired, or wrong-audience bearer JWT. Applies to\nboth user tokens (validated by calling auth's `/protected/jwt`) and\nservice tokens (validated locally against the shared `JWT_SECRET`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "no-token": {
                    "summary": "Missing Authorization header",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "missing bearer token"
                      }
                    }
                  },
                  "wrong-audience-user": {
                    "summary": "User JWT aud does not include payments",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token audience does not include 'payments' or 'default'"
                      }
                    }
                  },
                  "wrong-audience-service": {
                    "summary": "Service JWT presented with the wrong scoped audience",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "service token audience must be 'payments-service'"
                      }
                    }
                  },
                  "expired": {
                    "summary": "JWT exp in the past",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token expired"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error. Treat as transient; safe to retry with the same idempotency_key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-graphql-operations": [
          {
            "operationId": "proposeDeal",
            "kind": "mutation",
            "name": "proposeDeal",
            "service": "yieldfabric-dms",
            "tags": [
              "Deals"
            ],
            "summary": "Propose a new deal",
            "description": "Propose a new deal. Creates a `Proposed`-status row in `deal_instances`,\nmints the proposer's signature implicitly, and emits a `proposed` audit\nevent.\n\nIf `idempotency_key` is provided and a deal with the derived id already\nexists, returns that existing deal instead of inserting a duplicate — the\ncall becomes a no-op-shaped success response.\n\n**Auth:** caller must be authenticated. The proposer's `entity_id` is\ntaken from the JWT claims (`sub` or `acting_as`) — the proposer does not\npass their own `entity_id` in the input.\n\n**State transition:** `(none) → Proposed`. The proposer is implicitly\nrecorded as having signed; all other parties listed in `parties` must\ncountersign via `signDeal` before the deal can transition to `Accepted`.\n\n**On-chain effect:** none yet. Proposal is purely off-chain state in the\nDMS service. On-chain effects start at `activateDeal`.\n",
            "sdl": "mutation ProposeDeal($input: ProposeDealInput!) {\n  dealFlow {\n    proposeDeal(input: $input) {\n      success\n      deal {\n        id\n        status\n        name\n        parties { entityId role }\n      }\n      message\n    }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "description": "Input to `proposeDeal`. Caller must be authenticated; the proposer's\nentity is taken from JWT claims (the proposer doesn't pass their own\nentity_id — auth context is the source of truth).\n",
                "required": [
                  "parties",
                  "plan"
                ],
                "properties": {
                  "parties": {
                    "type": "array",
                    "description": "Counter-signing principals on this deal. Every entry must sign for\nthe deal to transition Proposed → Active. At least one entry is\nrequired at propose time; the validator rejects duplicate\n`entity_id`s and the proposer's own entity_id. Each `role` is a\nuser-authored IRI (`\"counterparty\"`, `\"lender\"`, `\"borrower\"`,\n`\"custodian\"`, …) that surfaces on the rendered agreement.\n",
                    "items": {
                      "type": "object",
                      "description": "One counter-signing party on a `ProposeDealInput`. Mirrors\n`data::types::deals::DealParty` (the persisted shape); kept as a\nseparate input type so the GraphQL surface stays explicit.\n",
                      "required": [
                        "entityId",
                        "role"
                      ],
                      "properties": {
                        "entityId": {
                          "type": "string"
                        },
                        "role": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "name": {
                    "type": "string",
                    "nullable": true,
                    "description": "Optional human-readable label for the deal. Stored on the deal\nrecord; surfaced as the card title on the listing page and the\ndetail-page header so users have a meaningful handle rather than\nthe opaque `DEAL-<uuid>`. Free-form; not unique.\n"
                  },
                  "plan": {
                    "description": "Arbitrary JSON value (object, array, scalar, or null)."
                  },
                  "cashflowRef": {
                    "type": "string",
                    "nullable": true,
                    "description": "Optional state-machine config name for periodic deals (e.g. \"mortgage\").\n`None` for one-shot deals.\n"
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true,
                    "description": "Optional idempotency key. Submitting the same key from the same\nproposer entity yields the same `DEAL-IDEMP-...` id and returns the\nexisting deal on retry instead of creating a duplicate.\n"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Two-party loan proposal with a tiny plan",
                  "value": {
                    "input": {
                      "name": "Q4 2027 working-capital loan",
                      "parties": [
                        {
                          "entityId": "user_bob_456",
                          "role": "borrower"
                        }
                      ],
                      "plan": {
                        "version": 1,
                        "cashflow_ref": null,
                        "nodes": [
                          {
                            "id": "send_principal",
                            "descriptor": "instant_send",
                            "inputs": {
                              "from": "$proposer.wallet",
                              "to": "$counterparty.wallet",
                              "amount": "1000000",
                              "asset": "USD"
                            }
                          }
                        ],
                        "edges": []
                      },
                      "idempotencyKey": "propose-q1-2026-loan-v1"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "deal": {
                    "type": "object",
                    "required": [
                      "id",
                      "kind",
                      "status",
                      "planHash",
                      "plan",
                      "proposerEntityId",
                      "parties",
                      "versionAt",
                      "deleted",
                      "transactionId",
                      "signatures",
                      "events",
                      "capabilities"
                    ],
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "kind": {
                        "type": "string",
                        "description": "Whether this row is a fully-fledged signed deal between two parties or\nan internal orchestration template.\n",
                        "enum": [
                          "SIGNED_DEAL",
                          "ORCHESTRATION"
                        ]
                      },
                      "name": {
                        "type": "string",
                        "nullable": true,
                        "description": "User-supplied label captured at `proposeDeal`. `None` when the\ncaller didn't supply one (orchestration-kind deals are always\n`None` — they're programmatically materialised, not user-named).\n"
                      },
                      "status": {
                        "type": "string",
                        "description": "Lifecycle status of a deal. Maps 1:1 to `data::types::deals::DealStatus`.\n",
                        "enum": [
                          "DRAFT",
                          "PROPOSED",
                          "ACCEPTED",
                          "COUNTER_OFFERED",
                          "REJECTED",
                          "ACTIVE",
                          "COMPLETED",
                          "CANCELLED",
                          "DEFAULTED",
                          "FAILED_AFTER_PARTIAL_EXECUTION"
                        ]
                      },
                      "planHash": {
                        "type": "string"
                      },
                      "plan": {
                        "description": "Arbitrary JSON value (object, array, scalar, or null)."
                      },
                      "proposerEntityId": {
                        "type": "string",
                        "description": "Proposer entity ID. Phase 2g will replace this with `proposer: Entity!`\nstitched from the auth subgraph; v1 exposes the raw ID string.\n"
                      },
                      "parties": {
                        "type": "array",
                        "description": "Counter-signing principals on this deal, in plan-authored order.\nEmpty list for orchestration-kind deals.\n",
                        "items": {
                          "type": "object",
                          "description": "One counter-signing principal on a deal. Returned as part of a Deal's\n`parties` field. The `role` is the user-authored IRI used in the plan\n(e.g. `\"counterparty\"`, `\"lender\"`, `\"borrower\"`, `\"custodian\"`).\n",
                          "required": [
                            "entityId",
                            "role"
                          ],
                          "properties": {
                            "entityId": {
                              "type": "string"
                            },
                            "role": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "parentDealId": {
                        "type": "string",
                        "nullable": true
                      },
                      "cashflowRef": {
                        "type": "string",
                        "nullable": true
                      },
                      "workflowId": {
                        "type": "string",
                        "nullable": true
                      },
                      "versionAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "acceptedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "completedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "cancelledAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "deleted": {
                        "type": "boolean"
                      },
                      "transactionId": {
                        "type": "string"
                      },
                      "signatures": {
                        "type": "array",
                        "description": "Signatures attached to this deal, ordered by `signed_at` ASC.\nEmpty list for `Orchestration` deals (no signatures expected).\nRequires `Arc<DealStore>` registered in the schema's context.\n",
                        "items": {
                          "type": "object",
                          "description": "One signature on a deal. Returned as part of a Deal's `signatures` field.\n",
                          "required": [
                            "dealId",
                            "role",
                            "partyEntityId",
                            "sigPayload",
                            "signedAt"
                          ],
                          "properties": {
                            "dealId": {
                              "type": "string"
                            },
                            "role": {
                              "type": "string"
                            },
                            "partyEntityId": {
                              "type": "string"
                            },
                            "sigPayload": {
                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                            },
                            "signedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      },
                      "events": {
                        "type": "array",
                        "description": "Audit-log events for this deal, ordered by `sequence` ASC.\nSequences are monotonic-but-not-dense within a deal.\n",
                        "items": {
                          "type": "object",
                          "description": "One audit-log entry for a deal.",
                          "required": [
                            "dealId",
                            "sequence",
                            "eventType",
                            "payload",
                            "occurredAt"
                          ],
                          "properties": {
                            "dealId": {
                              "type": "string"
                            },
                            "sequence": {
                              "type": "integer",
                              "description": "Monotonic-but-not-dense within a deal (BIGSERIAL is global)."
                            },
                            "eventType": {
                              "type": "string"
                            },
                            "actorEntityId": {
                              "type": "string",
                              "nullable": true,
                              "description": "`None` for system-emitted events (timer firings, scheduler ticks)."
                            },
                            "payload": {
                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                            },
                            "occurredAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      },
                      "capabilities": {
                        "type": "array",
                        "description": "Active (non-revoked) delegation capabilities for this deal.\nRevoked capabilities are filtered out — callers wanting full\nhistory should query a future `capabilityHistory` endpoint.\n",
                        "items": {
                          "type": "object",
                          "required": [
                            "id",
                            "dealId",
                            "grantedByEntityId",
                            "capabilityKind",
                            "allowedDescriptors",
                            "allowedParamConstraints",
                            "planHashBinding",
                            "grantedAt"
                          ],
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "dealId": {
                              "type": "string"
                            },
                            "grantedByEntityId": {
                              "type": "string"
                            },
                            "capabilityKind": {
                              "type": "string"
                            },
                            "walletId": {
                              "type": "string",
                              "nullable": true
                            },
                            "accountAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "allowedDescriptors": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "allowedParamConstraints": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "description": "One parameter constraint on a capability. Exposed as a typed GraphQL\ntype rather than opaque JSON so clients can render constraints in the\nUI without parsing.\n",
                                "required": [
                                  "descriptor",
                                  "field",
                                  "kind"
                                ],
                                "properties": {
                                  "descriptor": {
                                    "type": "string"
                                  },
                                  "field": {
                                    "type": "string"
                                  },
                                  "kind": {
                                    "description": "Constraint variants. Modeled as a GraphQL union of variant-specific\npayload types so clients can dispatch on `__typename`.\n",
                                    "oneOf": [
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "values"
                                        ],
                                        "properties": {
                                          "values": {
                                            "type": "array",
                                            "items": {
                                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                            }
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "type": "string"
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "type": "string"
                                          }
                                        }
                                      }
                                    ]
                                  }
                                }
                              }
                            },
                            "planHashBinding": {
                              "type": "string"
                            },
                            "grantedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            },
                            "revokedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      }
                    }
                  },
                  "message": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Plan failed structural validation (unknown descriptor, cyclic edges, duplicate party, proposer listed as a counterparty, etc.)."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload from the same proposer."
              },
              {
                "code": "INTERNAL_ERROR",
                "status": 500,
                "description": "Plan compile or persistence layer failed unexpectedly."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_proposeDeal",
              "resource_uri": "yf://deals",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/deals.yaml#/ProposeDealResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"mutation ProposeDeal($input: ProposeDealInput!) { dealFlow { proposeDeal(input: $input) { success deal { id status } message } } }\",\n    \"variables\": {\n      \"input\": {\n        \"name\": \"Q4 2027 loan\",\n        \"parties\": [{ \"entityId\": \"user_bob_456\", \"role\": \"borrower\" }],\n        \"plan\": { \"version\": 1, \"nodes\": [], \"edges\": [] }\n      }\n    }\n  }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nquery = \"\"\"\nmutation ProposeDeal($input: ProposeDealInput!) {\n  dealFlow {\n    proposeDeal(input: $input) {\n      success\n      deal { id status }\n      message\n    }\n  }\n}\n\"\"\"\nvariables = {\n    \"input\": {\n        \"name\": \"Q4 2027 loan\",\n        \"parties\": [{\"entityId\": \"user_bob_456\", \"role\": \"borrower\"}],\n        \"plan\": {\"version\": 1, \"nodes\": [], \"edges\": []},\n    }\n}\nr = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\"},\n    json={\"query\": query, \"variables\": variables},\n)\nprint(r.json()[\"data\"][\"dealFlow\"][\"proposeDeal\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst PROPOSE_DEAL = gql`\n  mutation ProposeDeal($input: ProposeDealInput!) {\n    dealFlow {\n      proposeDeal(input: $input) {\n        success\n        deal { id status }\n        message\n      }\n    }\n  }\n`;\n\nconst data = await client.request(PROPOSE_DEAL, {\n  input: {\n    name: \"Q4 2027 loan\",\n    parties: [{ entityId: \"user_bob_456\", role: \"borrower\" }],\n    plan: { version: 1, nodes: [], edges: [] },\n  },\n});\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation ProposeDeal($input: ProposeDealInput!) {\n  dealFlow {\n    proposeDeal(input: $input) {\n      success\n      deal {\n        id\n        status\n        name\n        parties { entityId role }\n      }\n      message\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "signDeal",
                "relation": "next"
              },
              {
                "operation": "activateDeal",
                "relation": "next"
              },
              {
                "operation": "counterOfferDeal",
                "relation": "alternative"
              },
              {
                "operation": "cancelDeal",
                "relation": "undo"
              },
              {
                "operation": "rejectDeal",
                "relation": "alternative"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "signDeal",
            "kind": "mutation",
            "name": "signDeal",
            "service": "yieldfabric-dms",
            "tags": [
              "Deals"
            ],
            "summary": "Sign a proposed deal",
            "description": "A counter-signing party signs a `Proposed` deal. When the last\noutstanding party signs, the deal transitions Proposed → Accepted (and\nbecomes eligible for `activateDeal`). While other parties still owe\nsignatures, the deal stays in `Proposed`.\n\nStamps `accepted_at` and appends a `signed` event.\n\n**Auth:** caller must be one of the parties listed in `deal.parties` who\nhas NOT yet signed. The proposer's signature is implicit at propose\ntime, so the proposer cannot call `signDeal` on their own deal.\n\n**State transitions:**\n- `Proposed → Proposed` while outstanding signatures remain\n- `Proposed → Accepted` when this signature is the last outstanding one\n\n**On-chain effect:** none. Signatures are off-chain JWT-attested.\n",
            "sdl": "mutation SignDeal($input: SignDealInput!) {\n  dealFlow {\n    signDeal(input: $input) {\n      success\n      deal {\n        id\n        status\n        signatures { partyEntityId role signedAt }\n      }\n      message\n    }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "dealId"
                ],
                "properties": {
                  "dealId": {
                    "type": "string"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Counterparty signs a proposed deal",
                  "value": {
                    "input": {
                      "dealId": "DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "deal": {
                    "type": "object",
                    "required": [
                      "id",
                      "kind",
                      "status",
                      "planHash",
                      "plan",
                      "proposerEntityId",
                      "parties",
                      "versionAt",
                      "deleted",
                      "transactionId",
                      "signatures",
                      "events",
                      "capabilities"
                    ],
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "kind": {
                        "type": "string",
                        "description": "Whether this row is a fully-fledged signed deal between two parties or\nan internal orchestration template.\n",
                        "enum": [
                          "SIGNED_DEAL",
                          "ORCHESTRATION"
                        ]
                      },
                      "name": {
                        "type": "string",
                        "nullable": true,
                        "description": "User-supplied label captured at `proposeDeal`. `None` when the\ncaller didn't supply one (orchestration-kind deals are always\n`None` — they're programmatically materialised, not user-named).\n"
                      },
                      "status": {
                        "type": "string",
                        "description": "Lifecycle status of a deal. Maps 1:1 to `data::types::deals::DealStatus`.\n",
                        "enum": [
                          "DRAFT",
                          "PROPOSED",
                          "ACCEPTED",
                          "COUNTER_OFFERED",
                          "REJECTED",
                          "ACTIVE",
                          "COMPLETED",
                          "CANCELLED",
                          "DEFAULTED",
                          "FAILED_AFTER_PARTIAL_EXECUTION"
                        ]
                      },
                      "planHash": {
                        "type": "string"
                      },
                      "plan": {
                        "description": "Arbitrary JSON value (object, array, scalar, or null)."
                      },
                      "proposerEntityId": {
                        "type": "string",
                        "description": "Proposer entity ID. Phase 2g will replace this with `proposer: Entity!`\nstitched from the auth subgraph; v1 exposes the raw ID string.\n"
                      },
                      "parties": {
                        "type": "array",
                        "description": "Counter-signing principals on this deal, in plan-authored order.\nEmpty list for orchestration-kind deals.\n",
                        "items": {
                          "type": "object",
                          "description": "One counter-signing principal on a deal. Returned as part of a Deal's\n`parties` field. The `role` is the user-authored IRI used in the plan\n(e.g. `\"counterparty\"`, `\"lender\"`, `\"borrower\"`, `\"custodian\"`).\n",
                          "required": [
                            "entityId",
                            "role"
                          ],
                          "properties": {
                            "entityId": {
                              "type": "string"
                            },
                            "role": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "parentDealId": {
                        "type": "string",
                        "nullable": true
                      },
                      "cashflowRef": {
                        "type": "string",
                        "nullable": true
                      },
                      "workflowId": {
                        "type": "string",
                        "nullable": true
                      },
                      "versionAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "acceptedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "completedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "cancelledAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "deleted": {
                        "type": "boolean"
                      },
                      "transactionId": {
                        "type": "string"
                      },
                      "signatures": {
                        "type": "array",
                        "description": "Signatures attached to this deal, ordered by `signed_at` ASC.\nEmpty list for `Orchestration` deals (no signatures expected).\nRequires `Arc<DealStore>` registered in the schema's context.\n",
                        "items": {
                          "type": "object",
                          "description": "One signature on a deal. Returned as part of a Deal's `signatures` field.\n",
                          "required": [
                            "dealId",
                            "role",
                            "partyEntityId",
                            "sigPayload",
                            "signedAt"
                          ],
                          "properties": {
                            "dealId": {
                              "type": "string"
                            },
                            "role": {
                              "type": "string"
                            },
                            "partyEntityId": {
                              "type": "string"
                            },
                            "sigPayload": {
                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                            },
                            "signedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      },
                      "events": {
                        "type": "array",
                        "description": "Audit-log events for this deal, ordered by `sequence` ASC.\nSequences are monotonic-but-not-dense within a deal.\n",
                        "items": {
                          "type": "object",
                          "description": "One audit-log entry for a deal.",
                          "required": [
                            "dealId",
                            "sequence",
                            "eventType",
                            "payload",
                            "occurredAt"
                          ],
                          "properties": {
                            "dealId": {
                              "type": "string"
                            },
                            "sequence": {
                              "type": "integer",
                              "description": "Monotonic-but-not-dense within a deal (BIGSERIAL is global)."
                            },
                            "eventType": {
                              "type": "string"
                            },
                            "actorEntityId": {
                              "type": "string",
                              "nullable": true,
                              "description": "`None` for system-emitted events (timer firings, scheduler ticks)."
                            },
                            "payload": {
                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                            },
                            "occurredAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      },
                      "capabilities": {
                        "type": "array",
                        "description": "Active (non-revoked) delegation capabilities for this deal.\nRevoked capabilities are filtered out — callers wanting full\nhistory should query a future `capabilityHistory` endpoint.\n",
                        "items": {
                          "type": "object",
                          "required": [
                            "id",
                            "dealId",
                            "grantedByEntityId",
                            "capabilityKind",
                            "allowedDescriptors",
                            "allowedParamConstraints",
                            "planHashBinding",
                            "grantedAt"
                          ],
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "dealId": {
                              "type": "string"
                            },
                            "grantedByEntityId": {
                              "type": "string"
                            },
                            "capabilityKind": {
                              "type": "string"
                            },
                            "walletId": {
                              "type": "string",
                              "nullable": true
                            },
                            "accountAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "allowedDescriptors": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "allowedParamConstraints": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "description": "One parameter constraint on a capability. Exposed as a typed GraphQL\ntype rather than opaque JSON so clients can render constraints in the\nUI without parsing.\n",
                                "required": [
                                  "descriptor",
                                  "field",
                                  "kind"
                                ],
                                "properties": {
                                  "descriptor": {
                                    "type": "string"
                                  },
                                  "field": {
                                    "type": "string"
                                  },
                                  "kind": {
                                    "description": "Constraint variants. Modeled as a GraphQL union of variant-specific\npayload types so clients can dispatch on `__typename`.\n",
                                    "oneOf": [
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "values"
                                        ],
                                        "properties": {
                                          "values": {
                                            "type": "array",
                                            "items": {
                                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                            }
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "type": "string"
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "type": "string"
                                          }
                                        }
                                      }
                                    ]
                                  }
                                }
                              }
                            },
                            "planHashBinding": {
                              "type": "string"
                            },
                            "grantedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            },
                            "revokedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      }
                    }
                  },
                  "message": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Caller is not listed as a party on this deal, or has already signed."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "NOT_FOUND",
                "status": 404,
                "description": "No deal with the given `dealId`."
              },
              {
                "code": "DEAL_STATE_INVALID",
                "status": 409,
                "description": "Deal is not in `Proposed` status (e.g. already `Accepted`, `Cancelled`, `Rejected`, or `CounterOffered`)."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_signDeal",
              "resource_uri": "yf://deals",
              "idempotent": false,
              "output_schema_ref": "../../components/schemas/deals.yaml#/SignDealResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"mutation SignDeal($input: SignDealInput!) { dealFlow { signDeal(input: $input) { success deal { id status } message } } }\",\n    \"variables\": { \"input\": { \"dealId\": \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\" } }\n  }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nquery = \"\"\"\nmutation SignDeal($input: SignDealInput!) {\n  dealFlow {\n    signDeal(input: $input) {\n      success\n      deal { id status }\n      message\n    }\n  }\n}\n\"\"\"\nr = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\"},\n    json={\"query\": query, \"variables\": {\"input\": {\"dealId\": \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\"}}},\n)\nprint(r.json()[\"data\"][\"dealFlow\"][\"signDeal\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst SIGN_DEAL = gql`\n  mutation SignDeal($input: SignDealInput!) {\n    dealFlow {\n      signDeal(input: $input) {\n        success\n        deal { id status }\n        message\n      }\n    }\n  }\n`;\n\nconst data = await client.request(SIGN_DEAL, {\n  input: { dealId: \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\" },\n});\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation SignDeal($input: SignDealInput!) {\n  dealFlow {\n    signDeal(input: $input) {\n      success\n      deal {\n        id\n        status\n        signatures { partyEntityId role signedAt }\n      }\n      message\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "proposeDeal",
                "relation": "prev"
              },
              {
                "operation": "activateDeal",
                "relation": "next"
              },
              {
                "operation": "rejectDeal",
                "relation": "alternative"
              },
              {
                "operation": "counterOfferDeal",
                "relation": "alternative"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "activateDeal",
            "kind": "mutation",
            "name": "activateDeal",
            "service": "yieldfabric-dms",
            "tags": [
              "Deals"
            ],
            "summary": "Activate an accepted deal",
            "description": "Activate an `Accepted` deal — compiles its plan into a pipeline workflow\nand submits it to the agents-side runtime. Only the proposer can\nactivate (they get the abort opportunity between sign and activate).\n\nThe caller's own selected-chain account is checked immediately after the\nproposer authorization check. After state/plan validation, the service also\nverifies the proposer and every other principal. Both checks are read-only\nand occur before creating the agents workflow, seeding period rows, changing\nthe deal status, appending an activation event, or starting on-chain work.\nIf any principal is missing an account, the GraphQL error has\n`extensions.code: CHAIN_ACCOUNT_REQUIRED` plus `httpStatus`, `entityKind`,\n`entityId`, `chainId`, and `operation`.\n\n**Side effects on success:**\n1. Parses the signed plan back from `deal.plan` JSONB.\n2. Compiles `DealPlan → WorkflowDefinition` and POSTs it to agents-api,\n   which returns the parent `workflow_id`.\n3. Stores that id on `deal.workflow_id`, transitions status to `Active`,\n   and writes the `activated` row to `deal_events` — all in one\n   bitemporal version write.\n4. For periodic deals, seeds the `deal_periods` rows (one per forecast\n   period); the per-period child workflows are submitted lazily via\n   `processDealPeriod`.\n\n**Auth:** caller must be the proposer of the deal. Counterparties\ncannot activate.\n\n**State transition:** `Accepted → Active`.\n\n**On-chain effect:** indirect — the compiled workflow steps will issue\non-chain operations (`instant_send`, `create_obligation`, etc.) as they\nexecute on the agents runtime.\n",
            "sdl": "mutation ActivateDeal($input: ActivateDealInput!) {\n  dealFlow {\n    activateDeal(input: $input) {\n      success\n      deal {\n        id\n        status\n        workflowId\n      }\n      message\n    }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "dealId"
                ],
                "properties": {
                  "dealId": {
                    "type": "string"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Proposer activates an accepted deal",
                  "value": {
                    "input": {
                      "dealId": "DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "deal": {
                    "type": "object",
                    "required": [
                      "id",
                      "kind",
                      "status",
                      "planHash",
                      "plan",
                      "proposerEntityId",
                      "parties",
                      "versionAt",
                      "deleted",
                      "transactionId",
                      "signatures",
                      "events",
                      "capabilities"
                    ],
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "kind": {
                        "type": "string",
                        "description": "Whether this row is a fully-fledged signed deal between two parties or\nan internal orchestration template.\n",
                        "enum": [
                          "SIGNED_DEAL",
                          "ORCHESTRATION"
                        ]
                      },
                      "name": {
                        "type": "string",
                        "nullable": true,
                        "description": "User-supplied label captured at `proposeDeal`. `None` when the\ncaller didn't supply one (orchestration-kind deals are always\n`None` — they're programmatically materialised, not user-named).\n"
                      },
                      "status": {
                        "type": "string",
                        "description": "Lifecycle status of a deal. Maps 1:1 to `data::types::deals::DealStatus`.\n",
                        "enum": [
                          "DRAFT",
                          "PROPOSED",
                          "ACCEPTED",
                          "COUNTER_OFFERED",
                          "REJECTED",
                          "ACTIVE",
                          "COMPLETED",
                          "CANCELLED",
                          "DEFAULTED",
                          "FAILED_AFTER_PARTIAL_EXECUTION"
                        ]
                      },
                      "planHash": {
                        "type": "string"
                      },
                      "plan": {
                        "description": "Arbitrary JSON value (object, array, scalar, or null)."
                      },
                      "proposerEntityId": {
                        "type": "string",
                        "description": "Proposer entity ID. Phase 2g will replace this with `proposer: Entity!`\nstitched from the auth subgraph; v1 exposes the raw ID string.\n"
                      },
                      "parties": {
                        "type": "array",
                        "description": "Counter-signing principals on this deal, in plan-authored order.\nEmpty list for orchestration-kind deals.\n",
                        "items": {
                          "type": "object",
                          "description": "One counter-signing principal on a deal. Returned as part of a Deal's\n`parties` field. The `role` is the user-authored IRI used in the plan\n(e.g. `\"counterparty\"`, `\"lender\"`, `\"borrower\"`, `\"custodian\"`).\n",
                          "required": [
                            "entityId",
                            "role"
                          ],
                          "properties": {
                            "entityId": {
                              "type": "string"
                            },
                            "role": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "parentDealId": {
                        "type": "string",
                        "nullable": true
                      },
                      "cashflowRef": {
                        "type": "string",
                        "nullable": true
                      },
                      "workflowId": {
                        "type": "string",
                        "nullable": true
                      },
                      "versionAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "acceptedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "completedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "cancelledAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "deleted": {
                        "type": "boolean"
                      },
                      "transactionId": {
                        "type": "string"
                      },
                      "signatures": {
                        "type": "array",
                        "description": "Signatures attached to this deal, ordered by `signed_at` ASC.\nEmpty list for `Orchestration` deals (no signatures expected).\nRequires `Arc<DealStore>` registered in the schema's context.\n",
                        "items": {
                          "type": "object",
                          "description": "One signature on a deal. Returned as part of a Deal's `signatures` field.\n",
                          "required": [
                            "dealId",
                            "role",
                            "partyEntityId",
                            "sigPayload",
                            "signedAt"
                          ],
                          "properties": {
                            "dealId": {
                              "type": "string"
                            },
                            "role": {
                              "type": "string"
                            },
                            "partyEntityId": {
                              "type": "string"
                            },
                            "sigPayload": {
                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                            },
                            "signedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      },
                      "events": {
                        "type": "array",
                        "description": "Audit-log events for this deal, ordered by `sequence` ASC.\nSequences are monotonic-but-not-dense within a deal.\n",
                        "items": {
                          "type": "object",
                          "description": "One audit-log entry for a deal.",
                          "required": [
                            "dealId",
                            "sequence",
                            "eventType",
                            "payload",
                            "occurredAt"
                          ],
                          "properties": {
                            "dealId": {
                              "type": "string"
                            },
                            "sequence": {
                              "type": "integer",
                              "description": "Monotonic-but-not-dense within a deal (BIGSERIAL is global)."
                            },
                            "eventType": {
                              "type": "string"
                            },
                            "actorEntityId": {
                              "type": "string",
                              "nullable": true,
                              "description": "`None` for system-emitted events (timer firings, scheduler ticks)."
                            },
                            "payload": {
                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                            },
                            "occurredAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      },
                      "capabilities": {
                        "type": "array",
                        "description": "Active (non-revoked) delegation capabilities for this deal.\nRevoked capabilities are filtered out — callers wanting full\nhistory should query a future `capabilityHistory` endpoint.\n",
                        "items": {
                          "type": "object",
                          "required": [
                            "id",
                            "dealId",
                            "grantedByEntityId",
                            "capabilityKind",
                            "allowedDescriptors",
                            "allowedParamConstraints",
                            "planHashBinding",
                            "grantedAt"
                          ],
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "dealId": {
                              "type": "string"
                            },
                            "grantedByEntityId": {
                              "type": "string"
                            },
                            "capabilityKind": {
                              "type": "string"
                            },
                            "walletId": {
                              "type": "string",
                              "nullable": true
                            },
                            "accountAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "allowedDescriptors": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "allowedParamConstraints": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "description": "One parameter constraint on a capability. Exposed as a typed GraphQL\ntype rather than opaque JSON so clients can render constraints in the\nUI without parsing.\n",
                                "required": [
                                  "descriptor",
                                  "field",
                                  "kind"
                                ],
                                "properties": {
                                  "descriptor": {
                                    "type": "string"
                                  },
                                  "field": {
                                    "type": "string"
                                  },
                                  "kind": {
                                    "description": "Constraint variants. Modeled as a GraphQL union of variant-specific\npayload types so clients can dispatch on `__typename`.\n",
                                    "oneOf": [
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "values"
                                        ],
                                        "properties": {
                                          "values": {
                                            "type": "array",
                                            "items": {
                                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                            }
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "type": "string"
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "type": "string"
                                          }
                                        }
                                      }
                                    ]
                                  }
                                }
                              }
                            },
                            "planHashBinding": {
                              "type": "string"
                            },
                            "grantedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            },
                            "revokedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      }
                    }
                  },
                  "message": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            },
            "errors": [
              {
                "code": "CHAIN_ACCOUNT_REQUIRED",
                "status": 409,
                "description": "The proposer or another principal has no account on the selected chain.\nGraphQL transport normally remains HTTP 200; `status` is carried as\n`errors[].extensions.httpStatus`. If it names the current actor, activate\nthat actor/chain, refresh the same actor's session, and retry once. If it\nnames another principal, that principal must activate their own account\nbefore the proposer retries; the caller must not deploy it for them.\n"
              },
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Plan failed to compile against the action registry, or the agents-api submission was rejected."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "FORBIDDEN",
                "status": 403,
                "description": "Caller is not the proposer of this deal."
              },
              {
                "code": "NOT_FOUND",
                "status": 404,
                "description": "No deal with the given `dealId`."
              },
              {
                "code": "DEAL_STATE_INVALID",
                "status": 409,
                "description": "Deal is not in `Accepted` status."
              },
              {
                "code": "INTERNAL_ERROR",
                "status": 500,
                "description": "Agents-api submission failed or the runtime returned an error."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_activateDeal",
              "resource_uri": "yf://deals",
              "idempotent": false,
              "output_schema_ref": "../../components/schemas/deals.yaml#/ActivateDealResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"mutation ActivateDeal($input: ActivateDealInput!) { dealFlow { activateDeal(input: $input) { success deal { id status workflowId } message } } }\",\n    \"variables\": { \"input\": { \"dealId\": \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\" } }\n  }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nquery = \"\"\"\nmutation ActivateDeal($input: ActivateDealInput!) {\n  dealFlow {\n    activateDeal(input: $input) {\n      success\n      deal { id status workflowId }\n      message\n    }\n  }\n}\n\"\"\"\nr = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\"},\n    json={\"query\": query, \"variables\": {\"input\": {\"dealId\": \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\"}}},\n)\nprint(r.json()[\"data\"][\"dealFlow\"][\"activateDeal\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst ACTIVATE_DEAL = gql`\n  mutation ActivateDeal($input: ActivateDealInput!) {\n    dealFlow {\n      activateDeal(input: $input) {\n        success\n        deal { id status workflowId }\n        message\n      }\n    }\n  }\n`;\n\nconst data = await client.request(ACTIVATE_DEAL, {\n  input: { dealId: \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\" },\n});\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation ActivateDeal($input: ActivateDealInput!) {\n  dealFlow {\n    activateDeal(input: $input) {\n      success\n      deal {\n        id\n        status\n        workflowId\n      }\n      message\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "signDeal",
                "relation": "prev"
              },
              {
                "operation": "cancelDeal",
                "relation": "alternative"
              },
              {
                "operation": "proposeDeal",
                "relation": "prev"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "runAgreement",
            "kind": "mutation",
            "name": "runAgreement",
            "service": "yieldfabric-dms",
            "tags": [
              "Deals"
            ],
            "summary": "Start or resume agreement execution",
            "description": "Starts or resumes the in-session driver for the caller's ready deal steps.\nA live RUNNING driver is joined idempotently instead of duplicated.\n\nDMS verifies the caller's selected-chain account after read-only deal state\nand principal checks, but before reclaiming/acquiring a run row, appending a\nrun-start event, or spawning the driver. A missing account therefore returns\n`CHAIN_ACCOUNT_REQUIRED` without creating a durable run transition. Activate\nthe returned entity and chain, refresh the same actor's JWT, and retry once.\n",
            "sdl": "mutation RunAgreement($input: RunAgreementInput!) {\n  dealFlow {\n    runAgreement(input: $input) {\n      started\n      dealId\n      status\n      message\n    }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "dealId"
                ],
                "properties": {
                  "dealId": {
                    "type": "string"
                  }
                }
              },
              "examples": {
                "resume": {
                  "value": {
                    "input": {
                      "dealId": "DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "started",
                  "dealId",
                  "status"
                ],
                "properties": {
                  "started": {
                    "type": "boolean",
                    "description": "False when an existing RUNNING driver was joined idempotently."
                  },
                  "dealId": {
                    "type": "string"
                  },
                  "status": {
                    "type": "string"
                  },
                  "message": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            },
            "errors": [
              {
                "code": "CHAIN_ACCOUNT_REQUIRED",
                "status": 409,
                "description": "The effective caller has no account on the selected chain. GraphQL\ntransport normally remains HTTP 200; inspect `errors[].extensions` for\n`entityKind`, `entityId`, `chainId`, and `operation`.\n"
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_runAgreement",
              "resource_uri": "yf://deals",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/deals.yaml#/RunAgreementResponse"
            },
            "x-codeSamples": [
              {
                "lang": "graphql",
                "label": "GraphQL",
                "source": "mutation RunAgreement($input: RunAgreementInput!) {\n  dealFlow { runAgreement(input: $input) { started dealId status message } }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "activateDeal",
                "relation": "prerequisite"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "processDealPeriod",
            "kind": "mutation",
            "name": "processDealPeriod",
            "service": "yieldfabric-dms",
            "tags": [
              "Deals"
            ],
            "summary": "Process one periodic-deal period",
            "description": "Materialises one scheduled period, compiles it into a child workflow, and\nsubmits it to the agents runtime. Terminal or already-processing periods\nkeep their existing idempotent read-only return.\n\nBefore a scheduled period is compiled or any period/workflow state is\nwritten, DMS verifies selected-chain accounts for the caller and every deal\nprincipal. A missing account returns `CHAIN_ACCOUNT_REQUIRED`; activate the\ncurrent actor and chain, refresh that same actor's JWT, and retry once. If\nanother principal is named, that principal must activate their own account\nbefore the caller retries; the caller must not activate it for them.\n",
            "sdl": "mutation ProcessDealPeriod($input: ProcessDealPeriodInput!) {\n  dealFlow {\n    processDealPeriod(input: $input) {\n      success\n      dealId\n      periodIndex\n      status\n      message\n    }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "dealId",
                  "periodIndex"
                ],
                "properties": {
                  "dealId": {
                    "type": "string"
                  },
                  "periodIndex": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              },
              "examples": {
                "first-period": {
                  "value": {
                    "input": {
                      "dealId": "DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f",
                      "periodIndex": 0
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "dealId",
                  "periodIndex",
                  "status"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "dealId": {
                    "type": "string"
                  },
                  "periodIndex": {
                    "type": "integer"
                  },
                  "status": {
                    "type": "string",
                    "description": "SCHEDULED, PROCESSING, COMPLETED, or FAILED."
                  },
                  "message": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            },
            "errors": [
              {
                "code": "CHAIN_ACCOUNT_REQUIRED",
                "status": 409,
                "description": "A required principal has no account on the selected chain. GraphQL\ntransport normally remains HTTP 200; inspect the camelCase fields in\n`errors[].extensions`.\n"
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_processDealPeriod",
              "resource_uri": "yf://deals",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/deals.yaml#/ProcessDealPeriodResponse"
            },
            "x-codeSamples": [
              {
                "lang": "graphql",
                "label": "GraphQL",
                "source": "mutation ProcessDealPeriod($input: ProcessDealPeriodInput!) {\n  dealFlow {\n    processDealPeriod(input: $input) { success dealId periodIndex status message }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "activateDeal",
                "relation": "prerequisite"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "completePartyAction",
            "kind": "mutation",
            "name": "completePartyAction",
            "service": "yieldfabric-dms",
            "tags": [
              "Deals"
            ],
            "summary": "Complete a pending party action",
            "description": "Completes a pending Party-kind action assigned to the effective caller. For\na workflow-backed action, DMS verifies the caller's account on the\nJWT-selected chain after read-only action/authorization checks but before\nacquiring the action (`PENDING → IN_PROGRESS`), signing the workflow step,\ncompleting the inbox row, or appending the deal event.\n\nA missing account returns `CHAIN_ACCOUNT_REQUIRED` in GraphQL extensions;\nno inbox state is consumed. Activate the returned entity and chain, refresh\nthe same actor's JWT, and retry the same mutation once.\n",
            "sdl": "mutation CompletePartyAction($input: CompletePartyActionInput!) {\n  dealFlow {\n    completePartyAction(input: $input) {\n      success\n      action { id dealId stepId status }\n      message\n    }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "description": "Complete one workflow-backed action assigned to the caller.",
                "required": [
                  "actionId"
                ],
                "properties": {
                  "actionId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "outputs": {
                    "description": "Arbitrary JSON value (object, array, scalar, or null)."
                  }
                }
              },
              "examples": {
                "confirm": {
                  "value": {
                    "input": {
                      "actionId": "7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f",
                      "outputs": {}
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "action": {
                    "type": "object",
                    "required": [
                      "id",
                      "dealId",
                      "stepId",
                      "descriptorName",
                      "assigneeKind",
                      "descriptorInputs",
                      "expectedOutputsSchema",
                      "status",
                      "createdAt"
                    ],
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "dealId": {
                        "type": "string"
                      },
                      "workflowId": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "description": "Pipeline-runtime workflow id, when known."
                      },
                      "stepId": {
                        "type": "string"
                      },
                      "descriptorName": {
                        "type": "string"
                      },
                      "assigneeKind": {
                        "type": "string",
                        "description": "\"ENTITY\" or \"ACCOUNT_ADDRESS\"."
                      },
                      "assigneeEntityId": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "assigneeAccountAddress": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "descriptorInputs": {
                        "description": "Arbitrary JSON value (object, array, scalar, or null)."
                      },
                      "expectedOutputsSchema": {
                        "description": "Arbitrary JSON value (object, array, scalar, or null)."
                      },
                      "status": {
                        "type": "string",
                        "enum": [
                          "PENDING",
                          "IN_PROGRESS",
                          "COMPLETED",
                          "CANCELLED",
                          "EXPIRED"
                        ]
                      },
                      "createdAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "expiresAt": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "format": "date-time"
                      },
                      "completedAt": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "format": "date-time"
                      },
                      "completedBy": {
                        "type": [
                          "string",
                          "null"
                        ]
                      },
                      "outputPayload": {
                        "description": "Arbitrary JSON value (object, array, scalar, or null)."
                      }
                    }
                  },
                  "message": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            },
            "errors": [
              {
                "code": "CHAIN_ACCOUNT_REQUIRED",
                "status": 409,
                "description": "The effective caller has no account on the selected chain. GraphQL\ntransport normally remains HTTP 200; inspect `errors[].extensions` for\n`entityKind`, `entityId`, `chainId`, and `operation`.\n"
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_completePartyAction",
              "resource_uri": "yf://deals",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/deals.yaml#/CompletePartyActionResponse"
            },
            "x-codeSamples": [
              {
                "lang": "graphql",
                "label": "GraphQL",
                "source": "mutation CompletePartyAction($input: CompletePartyActionInput!) {\n  dealFlow {\n    completePartyAction(input: $input) {\n      success\n      action { id dealId stepId status }\n      message\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "activateDeal",
                "relation": "prerequisite"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "rejectDeal",
            "kind": "mutation",
            "name": "rejectDeal",
            "service": "yieldfabric-dms",
            "tags": [
              "Deals"
            ],
            "summary": "Reject a proposed deal",
            "description": "Any counter-signing party rejects a `Proposed` deal. Moves the deal to\n`Rejected` — one rejection kills the deal for everyone, since the legal\nagreement requires every party's signature.\n\nThe proposer can re-propose under a new id if needed (or use\n`counterOfferDeal` from the rejecter's side to negotiate).\n\n**Auth:** caller must be a counterparty listed on the deal. The\nproposer cannot use this mutation — they should call `cancelDeal`\ninstead.\n\n**State transition:** `Proposed → Rejected`. Terminal.\n\n**On-chain effect:** none. The deal never reached activation.\n",
            "sdl": "mutation RejectDeal($input: RejectDealInput!) {\n  dealFlow {\n    rejectDeal(input: $input) {\n      success\n      deal {\n        id\n        status\n      }\n      message\n    }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "dealId"
                ],
                "properties": {
                  "dealId": {
                    "type": "string"
                  },
                  "reason": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Counterparty rejects with an optional reason",
                  "value": {
                    "input": {
                      "dealId": "DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f",
                      "reason": "Interest rate is above our policy ceiling"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "deal": {
                    "type": "object",
                    "required": [
                      "id",
                      "kind",
                      "status",
                      "planHash",
                      "plan",
                      "proposerEntityId",
                      "parties",
                      "versionAt",
                      "deleted",
                      "transactionId",
                      "signatures",
                      "events",
                      "capabilities"
                    ],
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "kind": {
                        "type": "string",
                        "description": "Whether this row is a fully-fledged signed deal between two parties or\nan internal orchestration template.\n",
                        "enum": [
                          "SIGNED_DEAL",
                          "ORCHESTRATION"
                        ]
                      },
                      "name": {
                        "type": "string",
                        "nullable": true,
                        "description": "User-supplied label captured at `proposeDeal`. `None` when the\ncaller didn't supply one (orchestration-kind deals are always\n`None` — they're programmatically materialised, not user-named).\n"
                      },
                      "status": {
                        "type": "string",
                        "description": "Lifecycle status of a deal. Maps 1:1 to `data::types::deals::DealStatus`.\n",
                        "enum": [
                          "DRAFT",
                          "PROPOSED",
                          "ACCEPTED",
                          "COUNTER_OFFERED",
                          "REJECTED",
                          "ACTIVE",
                          "COMPLETED",
                          "CANCELLED",
                          "DEFAULTED",
                          "FAILED_AFTER_PARTIAL_EXECUTION"
                        ]
                      },
                      "planHash": {
                        "type": "string"
                      },
                      "plan": {
                        "description": "Arbitrary JSON value (object, array, scalar, or null)."
                      },
                      "proposerEntityId": {
                        "type": "string",
                        "description": "Proposer entity ID. Phase 2g will replace this with `proposer: Entity!`\nstitched from the auth subgraph; v1 exposes the raw ID string.\n"
                      },
                      "parties": {
                        "type": "array",
                        "description": "Counter-signing principals on this deal, in plan-authored order.\nEmpty list for orchestration-kind deals.\n",
                        "items": {
                          "type": "object",
                          "description": "One counter-signing principal on a deal. Returned as part of a Deal's\n`parties` field. The `role` is the user-authored IRI used in the plan\n(e.g. `\"counterparty\"`, `\"lender\"`, `\"borrower\"`, `\"custodian\"`).\n",
                          "required": [
                            "entityId",
                            "role"
                          ],
                          "properties": {
                            "entityId": {
                              "type": "string"
                            },
                            "role": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "parentDealId": {
                        "type": "string",
                        "nullable": true
                      },
                      "cashflowRef": {
                        "type": "string",
                        "nullable": true
                      },
                      "workflowId": {
                        "type": "string",
                        "nullable": true
                      },
                      "versionAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "acceptedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "completedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "cancelledAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "deleted": {
                        "type": "boolean"
                      },
                      "transactionId": {
                        "type": "string"
                      },
                      "signatures": {
                        "type": "array",
                        "description": "Signatures attached to this deal, ordered by `signed_at` ASC.\nEmpty list for `Orchestration` deals (no signatures expected).\nRequires `Arc<DealStore>` registered in the schema's context.\n",
                        "items": {
                          "type": "object",
                          "description": "One signature on a deal. Returned as part of a Deal's `signatures` field.\n",
                          "required": [
                            "dealId",
                            "role",
                            "partyEntityId",
                            "sigPayload",
                            "signedAt"
                          ],
                          "properties": {
                            "dealId": {
                              "type": "string"
                            },
                            "role": {
                              "type": "string"
                            },
                            "partyEntityId": {
                              "type": "string"
                            },
                            "sigPayload": {
                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                            },
                            "signedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      },
                      "events": {
                        "type": "array",
                        "description": "Audit-log events for this deal, ordered by `sequence` ASC.\nSequences are monotonic-but-not-dense within a deal.\n",
                        "items": {
                          "type": "object",
                          "description": "One audit-log entry for a deal.",
                          "required": [
                            "dealId",
                            "sequence",
                            "eventType",
                            "payload",
                            "occurredAt"
                          ],
                          "properties": {
                            "dealId": {
                              "type": "string"
                            },
                            "sequence": {
                              "type": "integer",
                              "description": "Monotonic-but-not-dense within a deal (BIGSERIAL is global)."
                            },
                            "eventType": {
                              "type": "string"
                            },
                            "actorEntityId": {
                              "type": "string",
                              "nullable": true,
                              "description": "`None` for system-emitted events (timer firings, scheduler ticks)."
                            },
                            "payload": {
                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                            },
                            "occurredAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      },
                      "capabilities": {
                        "type": "array",
                        "description": "Active (non-revoked) delegation capabilities for this deal.\nRevoked capabilities are filtered out — callers wanting full\nhistory should query a future `capabilityHistory` endpoint.\n",
                        "items": {
                          "type": "object",
                          "required": [
                            "id",
                            "dealId",
                            "grantedByEntityId",
                            "capabilityKind",
                            "allowedDescriptors",
                            "allowedParamConstraints",
                            "planHashBinding",
                            "grantedAt"
                          ],
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "dealId": {
                              "type": "string"
                            },
                            "grantedByEntityId": {
                              "type": "string"
                            },
                            "capabilityKind": {
                              "type": "string"
                            },
                            "walletId": {
                              "type": "string",
                              "nullable": true
                            },
                            "accountAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "allowedDescriptors": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "allowedParamConstraints": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "description": "One parameter constraint on a capability. Exposed as a typed GraphQL\ntype rather than opaque JSON so clients can render constraints in the\nUI without parsing.\n",
                                "required": [
                                  "descriptor",
                                  "field",
                                  "kind"
                                ],
                                "properties": {
                                  "descriptor": {
                                    "type": "string"
                                  },
                                  "field": {
                                    "type": "string"
                                  },
                                  "kind": {
                                    "description": "Constraint variants. Modeled as a GraphQL union of variant-specific\npayload types so clients can dispatch on `__typename`.\n",
                                    "oneOf": [
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "values"
                                        ],
                                        "properties": {
                                          "values": {
                                            "type": "array",
                                            "items": {
                                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                            }
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "type": "string"
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "type": "string"
                                          }
                                        }
                                      }
                                    ]
                                  }
                                }
                              }
                            },
                            "planHashBinding": {
                              "type": "string"
                            },
                            "grantedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            },
                            "revokedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      }
                    }
                  },
                  "message": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Caller is not a counterparty on this deal."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "NOT_FOUND",
                "status": 404,
                "description": "No deal with the given `dealId`."
              },
              {
                "code": "DEAL_STATE_INVALID",
                "status": 409,
                "description": "Deal is not in `Proposed` status."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_rejectDeal",
              "resource_uri": "yf://deals",
              "idempotent": false,
              "output_schema_ref": "../../components/schemas/deals.yaml#/RejectDealResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"mutation RejectDeal($input: RejectDealInput!) { dealFlow { rejectDeal(input: $input) { success deal { id status } message } } }\",\n    \"variables\": { \"input\": { \"dealId\": \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\", \"reason\": \"rate too high\" } }\n  }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nquery = \"\"\"\nmutation RejectDeal($input: RejectDealInput!) {\n  dealFlow {\n    rejectDeal(input: $input) {\n      success\n      deal { id status }\n      message\n    }\n  }\n}\n\"\"\"\nr = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\"},\n    json={\"query\": query, \"variables\": {\"input\": {\"dealId\": \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\", \"reason\": \"rate too high\"}}},\n)\nprint(r.json()[\"data\"][\"dealFlow\"][\"rejectDeal\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst REJECT_DEAL = gql`\n  mutation RejectDeal($input: RejectDealInput!) {\n    dealFlow {\n      rejectDeal(input: $input) {\n        success\n        deal { id status }\n        message\n      }\n    }\n  }\n`;\n\nconst data = await client.request(REJECT_DEAL, {\n  input: {\n    dealId: \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\",\n    reason: \"rate too high\",\n  },\n});\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation RejectDeal($input: RejectDealInput!) {\n  dealFlow {\n    rejectDeal(input: $input) {\n      success\n      deal {\n        id\n        status\n      }\n      message\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "signDeal",
                "relation": "alternative"
              },
              {
                "operation": "counterOfferDeal",
                "relation": "alternative"
              },
              {
                "operation": "proposeDeal",
                "relation": "prev"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "counterOfferDeal",
            "kind": "mutation",
            "name": "counterOfferDeal",
            "service": "yieldfabric-dms",
            "tags": [
              "Deals"
            ],
            "summary": "Counter-offer a proposed deal",
            "description": "Counter-offer a `Proposed` deal. Creates a new child deal where the\ncaller is the proposer (roles swap relative to parent), and transitions\nthe parent to `CounterOffered`.\n\nSubmitting a counter-offer is the recommended path when a counterparty\nwants to renegotiate rather than outright `rejectDeal` — it keeps the\nthread (parent → child) linked for audit and lets the original proposer\nsee the proposed amendments side-by-side.\n\n`idempotency_key` (if provided) yields a deterministic child id and\nshort-circuits to the existing child on retry. The parent transition is\nalso short-circuited — re-running an already-counter-offered flow is a\nno-op.\n\n**Auth:** caller must be a counterparty on the parent deal.\n\n**State transitions:**\n- Parent: `Proposed → CounterOffered` (terminal for the parent)\n- Child: `(none) → Proposed` (a fresh deal that follows the normal\n  propose/sign/activate lifecycle)\n\n**On-chain effect:** none. Counter-offers are off-chain state.\n",
            "sdl": "mutation CounterOfferDeal($input: CounterOfferDealInput!) {\n  dealFlow {\n    counterOfferDeal(input: $input) {\n      success\n      deal {\n        id\n        status\n        parentDealId\n      }\n      message\n    }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "description": "Submit a counter-offer to a Proposed deal. Creates a new child deal\n(with `parent_deal_id` linking to the parent) and moves the parent to\n`COUNTER_OFFERED`. The caller becomes the proposer of the child;\nroles swap relative to the parent.\n",
                "required": [
                  "parentDealId",
                  "plan"
                ],
                "properties": {
                  "parentDealId": {
                    "type": "string"
                  },
                  "plan": {
                    "description": "Arbitrary JSON value (object, array, scalar, or null)."
                  },
                  "cashflowRef": {
                    "type": "string",
                    "nullable": true
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true,
                    "description": "Optional idempotency key for the child deal. See\n`ProposeDealInput::idempotency_key` for semantics.\n"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Counterparty submits a child deal with revised terms",
                  "value": {
                    "input": {
                      "parentDealId": "DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f",
                      "plan": {
                        "version": 1,
                        "cashflow_ref": null,
                        "nodes": [
                          {
                            "id": "send_principal",
                            "descriptor": "instant_send",
                            "inputs": {
                              "from": "$proposer.wallet",
                              "to": "$counterparty.wallet",
                              "amount": "950000",
                              "asset": "USD"
                            }
                          }
                        ],
                        "edges": []
                      },
                      "idempotencyKey": "counter-2026-loan-rev1"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "deal": {
                    "type": "object",
                    "required": [
                      "id",
                      "kind",
                      "status",
                      "planHash",
                      "plan",
                      "proposerEntityId",
                      "parties",
                      "versionAt",
                      "deleted",
                      "transactionId",
                      "signatures",
                      "events",
                      "capabilities"
                    ],
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "kind": {
                        "type": "string",
                        "description": "Whether this row is a fully-fledged signed deal between two parties or\nan internal orchestration template.\n",
                        "enum": [
                          "SIGNED_DEAL",
                          "ORCHESTRATION"
                        ]
                      },
                      "name": {
                        "type": "string",
                        "nullable": true,
                        "description": "User-supplied label captured at `proposeDeal`. `None` when the\ncaller didn't supply one (orchestration-kind deals are always\n`None` — they're programmatically materialised, not user-named).\n"
                      },
                      "status": {
                        "type": "string",
                        "description": "Lifecycle status of a deal. Maps 1:1 to `data::types::deals::DealStatus`.\n",
                        "enum": [
                          "DRAFT",
                          "PROPOSED",
                          "ACCEPTED",
                          "COUNTER_OFFERED",
                          "REJECTED",
                          "ACTIVE",
                          "COMPLETED",
                          "CANCELLED",
                          "DEFAULTED",
                          "FAILED_AFTER_PARTIAL_EXECUTION"
                        ]
                      },
                      "planHash": {
                        "type": "string"
                      },
                      "plan": {
                        "description": "Arbitrary JSON value (object, array, scalar, or null)."
                      },
                      "proposerEntityId": {
                        "type": "string",
                        "description": "Proposer entity ID. Phase 2g will replace this with `proposer: Entity!`\nstitched from the auth subgraph; v1 exposes the raw ID string.\n"
                      },
                      "parties": {
                        "type": "array",
                        "description": "Counter-signing principals on this deal, in plan-authored order.\nEmpty list for orchestration-kind deals.\n",
                        "items": {
                          "type": "object",
                          "description": "One counter-signing principal on a deal. Returned as part of a Deal's\n`parties` field. The `role` is the user-authored IRI used in the plan\n(e.g. `\"counterparty\"`, `\"lender\"`, `\"borrower\"`, `\"custodian\"`).\n",
                          "required": [
                            "entityId",
                            "role"
                          ],
                          "properties": {
                            "entityId": {
                              "type": "string"
                            },
                            "role": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "parentDealId": {
                        "type": "string",
                        "nullable": true
                      },
                      "cashflowRef": {
                        "type": "string",
                        "nullable": true
                      },
                      "workflowId": {
                        "type": "string",
                        "nullable": true
                      },
                      "versionAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "acceptedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "completedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "cancelledAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "deleted": {
                        "type": "boolean"
                      },
                      "transactionId": {
                        "type": "string"
                      },
                      "signatures": {
                        "type": "array",
                        "description": "Signatures attached to this deal, ordered by `signed_at` ASC.\nEmpty list for `Orchestration` deals (no signatures expected).\nRequires `Arc<DealStore>` registered in the schema's context.\n",
                        "items": {
                          "type": "object",
                          "description": "One signature on a deal. Returned as part of a Deal's `signatures` field.\n",
                          "required": [
                            "dealId",
                            "role",
                            "partyEntityId",
                            "sigPayload",
                            "signedAt"
                          ],
                          "properties": {
                            "dealId": {
                              "type": "string"
                            },
                            "role": {
                              "type": "string"
                            },
                            "partyEntityId": {
                              "type": "string"
                            },
                            "sigPayload": {
                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                            },
                            "signedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      },
                      "events": {
                        "type": "array",
                        "description": "Audit-log events for this deal, ordered by `sequence` ASC.\nSequences are monotonic-but-not-dense within a deal.\n",
                        "items": {
                          "type": "object",
                          "description": "One audit-log entry for a deal.",
                          "required": [
                            "dealId",
                            "sequence",
                            "eventType",
                            "payload",
                            "occurredAt"
                          ],
                          "properties": {
                            "dealId": {
                              "type": "string"
                            },
                            "sequence": {
                              "type": "integer",
                              "description": "Monotonic-but-not-dense within a deal (BIGSERIAL is global)."
                            },
                            "eventType": {
                              "type": "string"
                            },
                            "actorEntityId": {
                              "type": "string",
                              "nullable": true,
                              "description": "`None` for system-emitted events (timer firings, scheduler ticks)."
                            },
                            "payload": {
                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                            },
                            "occurredAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      },
                      "capabilities": {
                        "type": "array",
                        "description": "Active (non-revoked) delegation capabilities for this deal.\nRevoked capabilities are filtered out — callers wanting full\nhistory should query a future `capabilityHistory` endpoint.\n",
                        "items": {
                          "type": "object",
                          "required": [
                            "id",
                            "dealId",
                            "grantedByEntityId",
                            "capabilityKind",
                            "allowedDescriptors",
                            "allowedParamConstraints",
                            "planHashBinding",
                            "grantedAt"
                          ],
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "dealId": {
                              "type": "string"
                            },
                            "grantedByEntityId": {
                              "type": "string"
                            },
                            "capabilityKind": {
                              "type": "string"
                            },
                            "walletId": {
                              "type": "string",
                              "nullable": true
                            },
                            "accountAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "allowedDescriptors": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "allowedParamConstraints": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "description": "One parameter constraint on a capability. Exposed as a typed GraphQL\ntype rather than opaque JSON so clients can render constraints in the\nUI without parsing.\n",
                                "required": [
                                  "descriptor",
                                  "field",
                                  "kind"
                                ],
                                "properties": {
                                  "descriptor": {
                                    "type": "string"
                                  },
                                  "field": {
                                    "type": "string"
                                  },
                                  "kind": {
                                    "description": "Constraint variants. Modeled as a GraphQL union of variant-specific\npayload types so clients can dispatch on `__typename`.\n",
                                    "oneOf": [
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "values"
                                        ],
                                        "properties": {
                                          "values": {
                                            "type": "array",
                                            "items": {
                                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                            }
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "type": "string"
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "type": "string"
                                          }
                                        }
                                      }
                                    ]
                                  }
                                }
                              }
                            },
                            "planHashBinding": {
                              "type": "string"
                            },
                            "grantedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            },
                            "revokedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      }
                    }
                  },
                  "message": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Plan failed structural validation, or caller is not a counterparty on the parent."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "NOT_FOUND",
                "status": 404,
                "description": "No deal with the given `parentDealId`."
              },
              {
                "code": "DEAL_STATE_INVALID",
                "status": 409,
                "description": "Parent deal is not in `Proposed` status (e.g. already `Accepted`, `Cancelled`, `Rejected`)."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload from the same caller."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_counterOfferDeal",
              "resource_uri": "yf://deals",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/deals.yaml#/CounterOfferDealResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"mutation CounterOfferDeal($input: CounterOfferDealInput!) { dealFlow { counterOfferDeal(input: $input) { success deal { id status parentDealId } message } } }\",\n    \"variables\": {\n      \"input\": {\n        \"parentDealId\": \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\",\n        \"plan\": { \"version\": 1, \"nodes\": [], \"edges\": [] }\n      }\n    }\n  }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nquery = \"\"\"\nmutation CounterOfferDeal($input: CounterOfferDealInput!) {\n  dealFlow {\n    counterOfferDeal(input: $input) {\n      success\n      deal { id status parentDealId }\n      message\n    }\n  }\n}\n\"\"\"\nvariables = {\n    \"input\": {\n        \"parentDealId\": \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\",\n        \"plan\": {\"version\": 1, \"nodes\": [], \"edges\": []},\n    }\n}\nr = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\"},\n    json={\"query\": query, \"variables\": variables},\n)\nprint(r.json()[\"data\"][\"dealFlow\"][\"counterOfferDeal\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst COUNTER_OFFER_DEAL = gql`\n  mutation CounterOfferDeal($input: CounterOfferDealInput!) {\n    dealFlow {\n      counterOfferDeal(input: $input) {\n        success\n        deal { id status parentDealId }\n        message\n      }\n    }\n  }\n`;\n\nconst data = await client.request(COUNTER_OFFER_DEAL, {\n  input: {\n    parentDealId: \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\",\n    plan: { version: 1, nodes: [], edges: [] },\n  },\n});\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation CounterOfferDeal($input: CounterOfferDealInput!) {\n  dealFlow {\n    counterOfferDeal(input: $input) {\n      success\n      deal {\n        id\n        status\n        parentDealId\n      }\n      message\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "proposeDeal",
                "relation": "alternative"
              },
              {
                "operation": "rejectDeal",
                "relation": "alternative"
              },
              {
                "operation": "signDeal",
                "relation": "alternative"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "cancelDeal",
            "kind": "mutation",
            "name": "cancelDeal",
            "service": "yieldfabric-dms",
            "tags": [
              "Deals"
            ],
            "summary": "Cancel a deal (pre-execution kill switch)",
            "description": "Cancel a deal. Allowed in `Proposed` (proposer-only — they're abandoning\ntheir own offer) and `Accepted` (either party — pre-execution kill\nswitch).\n\nActive deals can't be cancelled this way: once execution starts,\non-chain state and counterparty obligations exist that can't be\nunilaterally rolled back. Cancellation of an Active deal must come from\nthe plan itself — `OnFailure` edges, branch terminators, or a\ncompensating `cancel_obligation` / `cancel_swap` sequence the parties\npre-agreed at signing time. This guarantees the agreement stays the\nsource of truth for what either party can do post-activation.\n\nDual-signoff (both parties must agree) was considered for `Accepted`\ncancellation and rejected for v1: the pre-execution window is short,\nnothing has moved on chain yet, and forcing two-step coordination here\nadds UI complexity without protecting either party — the deal hasn't\nsettled yet so unilateral abort is symmetric for both. Revisit if\nsigned-but-unactivated deals start carrying real economic weight (e.g.\nreputational binding, deposit escrow).\n\n**Auth:**\n- `Proposed`: only the proposer may cancel.\n- `Accepted`: either the proposer or any counterparty may cancel.\n\n**State transitions:**\n- `Proposed → Cancelled`\n- `Accepted → Cancelled`\n\n**On-chain effect:** none. The deal never reached activation.\n",
            "sdl": "mutation CancelDeal($input: CancelDealInput!) {\n  dealFlow {\n    cancelDeal(input: $input) {\n      success\n      deal {\n        id\n        status\n      }\n      message\n    }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "dealId"
                ],
                "properties": {
                  "dealId": {
                    "type": "string"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Proposer cancels their own proposed deal",
                  "value": {
                    "input": {
                      "dealId": "DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "deal": {
                    "type": "object",
                    "required": [
                      "id",
                      "kind",
                      "status",
                      "planHash",
                      "plan",
                      "proposerEntityId",
                      "parties",
                      "versionAt",
                      "deleted",
                      "transactionId",
                      "signatures",
                      "events",
                      "capabilities"
                    ],
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "kind": {
                        "type": "string",
                        "description": "Whether this row is a fully-fledged signed deal between two parties or\nan internal orchestration template.\n",
                        "enum": [
                          "SIGNED_DEAL",
                          "ORCHESTRATION"
                        ]
                      },
                      "name": {
                        "type": "string",
                        "nullable": true,
                        "description": "User-supplied label captured at `proposeDeal`. `None` when the\ncaller didn't supply one (orchestration-kind deals are always\n`None` — they're programmatically materialised, not user-named).\n"
                      },
                      "status": {
                        "type": "string",
                        "description": "Lifecycle status of a deal. Maps 1:1 to `data::types::deals::DealStatus`.\n",
                        "enum": [
                          "DRAFT",
                          "PROPOSED",
                          "ACCEPTED",
                          "COUNTER_OFFERED",
                          "REJECTED",
                          "ACTIVE",
                          "COMPLETED",
                          "CANCELLED",
                          "DEFAULTED",
                          "FAILED_AFTER_PARTIAL_EXECUTION"
                        ]
                      },
                      "planHash": {
                        "type": "string"
                      },
                      "plan": {
                        "description": "Arbitrary JSON value (object, array, scalar, or null)."
                      },
                      "proposerEntityId": {
                        "type": "string",
                        "description": "Proposer entity ID. Phase 2g will replace this with `proposer: Entity!`\nstitched from the auth subgraph; v1 exposes the raw ID string.\n"
                      },
                      "parties": {
                        "type": "array",
                        "description": "Counter-signing principals on this deal, in plan-authored order.\nEmpty list for orchestration-kind deals.\n",
                        "items": {
                          "type": "object",
                          "description": "One counter-signing principal on a deal. Returned as part of a Deal's\n`parties` field. The `role` is the user-authored IRI used in the plan\n(e.g. `\"counterparty\"`, `\"lender\"`, `\"borrower\"`, `\"custodian\"`).\n",
                          "required": [
                            "entityId",
                            "role"
                          ],
                          "properties": {
                            "entityId": {
                              "type": "string"
                            },
                            "role": {
                              "type": "string"
                            }
                          }
                        }
                      },
                      "parentDealId": {
                        "type": "string",
                        "nullable": true
                      },
                      "cashflowRef": {
                        "type": "string",
                        "nullable": true
                      },
                      "workflowId": {
                        "type": "string",
                        "nullable": true
                      },
                      "versionAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "acceptedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "completedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "cancelledAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      },
                      "deleted": {
                        "type": "boolean"
                      },
                      "transactionId": {
                        "type": "string"
                      },
                      "signatures": {
                        "type": "array",
                        "description": "Signatures attached to this deal, ordered by `signed_at` ASC.\nEmpty list for `Orchestration` deals (no signatures expected).\nRequires `Arc<DealStore>` registered in the schema's context.\n",
                        "items": {
                          "type": "object",
                          "description": "One signature on a deal. Returned as part of a Deal's `signatures` field.\n",
                          "required": [
                            "dealId",
                            "role",
                            "partyEntityId",
                            "sigPayload",
                            "signedAt"
                          ],
                          "properties": {
                            "dealId": {
                              "type": "string"
                            },
                            "role": {
                              "type": "string"
                            },
                            "partyEntityId": {
                              "type": "string"
                            },
                            "sigPayload": {
                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                            },
                            "signedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      },
                      "events": {
                        "type": "array",
                        "description": "Audit-log events for this deal, ordered by `sequence` ASC.\nSequences are monotonic-but-not-dense within a deal.\n",
                        "items": {
                          "type": "object",
                          "description": "One audit-log entry for a deal.",
                          "required": [
                            "dealId",
                            "sequence",
                            "eventType",
                            "payload",
                            "occurredAt"
                          ],
                          "properties": {
                            "dealId": {
                              "type": "string"
                            },
                            "sequence": {
                              "type": "integer",
                              "description": "Monotonic-but-not-dense within a deal (BIGSERIAL is global)."
                            },
                            "eventType": {
                              "type": "string"
                            },
                            "actorEntityId": {
                              "type": "string",
                              "nullable": true,
                              "description": "`None` for system-emitted events (timer firings, scheduler ticks)."
                            },
                            "payload": {
                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                            },
                            "occurredAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      },
                      "capabilities": {
                        "type": "array",
                        "description": "Active (non-revoked) delegation capabilities for this deal.\nRevoked capabilities are filtered out — callers wanting full\nhistory should query a future `capabilityHistory` endpoint.\n",
                        "items": {
                          "type": "object",
                          "required": [
                            "id",
                            "dealId",
                            "grantedByEntityId",
                            "capabilityKind",
                            "allowedDescriptors",
                            "allowedParamConstraints",
                            "planHashBinding",
                            "grantedAt"
                          ],
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "dealId": {
                              "type": "string"
                            },
                            "grantedByEntityId": {
                              "type": "string"
                            },
                            "capabilityKind": {
                              "type": "string"
                            },
                            "walletId": {
                              "type": "string",
                              "nullable": true
                            },
                            "accountAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "allowedDescriptors": {
                              "type": "array",
                              "items": {
                                "type": "string"
                              }
                            },
                            "allowedParamConstraints": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "description": "One parameter constraint on a capability. Exposed as a typed GraphQL\ntype rather than opaque JSON so clients can render constraints in the\nUI without parsing.\n",
                                "required": [
                                  "descriptor",
                                  "field",
                                  "kind"
                                ],
                                "properties": {
                                  "descriptor": {
                                    "type": "string"
                                  },
                                  "field": {
                                    "type": "string"
                                  },
                                  "kind": {
                                    "description": "Constraint variants. Modeled as a GraphQL union of variant-specific\npayload types so clients can dispatch on `__typename`.\n",
                                    "oneOf": [
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "values"
                                        ],
                                        "properties": {
                                          "values": {
                                            "type": "array",
                                            "items": {
                                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                            }
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "type": "string"
                                          }
                                        }
                                      },
                                      {
                                        "type": "object",
                                        "required": [
                                          "value"
                                        ],
                                        "properties": {
                                          "value": {
                                            "type": "string"
                                          }
                                        }
                                      }
                                    ]
                                  }
                                }
                              }
                            },
                            "planHashBinding": {
                              "type": "string"
                            },
                            "grantedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            },
                            "revokedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      }
                    }
                  },
                  "message": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Caller is not authorised to cancel this deal in its current state."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "FORBIDDEN",
                "status": 403,
                "description": "Caller is a counterparty trying to cancel a `Proposed` deal (only the proposer can)."
              },
              {
                "code": "NOT_FOUND",
                "status": 404,
                "description": "No deal with the given `dealId`."
              },
              {
                "code": "DEAL_STATE_INVALID",
                "status": 409,
                "description": "Deal is `Active`, `Completed`, `Cancelled`, `Rejected`, or otherwise not in a cancellable state."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_cancelDeal",
              "resource_uri": "yf://deals",
              "idempotent": false,
              "output_schema_ref": "../../components/schemas/deals.yaml#/CancelDealResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"mutation CancelDeal($input: CancelDealInput!) { dealFlow { cancelDeal(input: $input) { success deal { id status } message } } }\",\n    \"variables\": { \"input\": { \"dealId\": \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\" } }\n  }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nquery = \"\"\"\nmutation CancelDeal($input: CancelDealInput!) {\n  dealFlow {\n    cancelDeal(input: $input) {\n      success\n      deal { id status }\n      message\n    }\n  }\n}\n\"\"\"\nr = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\"},\n    json={\"query\": query, \"variables\": {\"input\": {\"dealId\": \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\"}}},\n)\nprint(r.json()[\"data\"][\"dealFlow\"][\"cancelDeal\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst CANCEL_DEAL = gql`\n  mutation CancelDeal($input: CancelDealInput!) {\n    dealFlow {\n      cancelDeal(input: $input) {\n        success\n        deal { id status }\n        message\n      }\n    }\n  }\n`;\n\nconst data = await client.request(CANCEL_DEAL, {\n  input: { dealId: \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\" },\n});\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation CancelDeal($input: CancelDealInput!) {\n  dealFlow {\n    cancelDeal(input: $input) {\n      success\n      deal {\n        id\n        status\n      }\n      message\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "proposeDeal",
                "relation": "prev"
              },
              {
                "operation": "signDeal",
                "relation": "prev"
              },
              {
                "operation": "activateDeal",
                "relation": "alternative"
              },
              {
                "operation": "rejectDeal",
                "relation": "alternative"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "deposit",
            "kind": "mutation",
            "name": "deposit",
            "service": "yieldfabric-payments",
            "tags": [
              "Payments"
            ],
            "summary": "Fund the caller's vault with an asset",
            "description": "Move funds from the caller's external balance into their on-chain vault\nfor the named `assetId`. Required inputs are `assetId` (e.g. `\"USD\"`) and\n`amount` (raw integer string at the asset's native scale — typically 1e18\nwei units).\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4 is the canonical form) to\nmake retries safe — repeated calls with the same key return the original\nresult without re-spending funds.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. The caller's\nentity is taken from the JWT (`sub` or `acting_as`). When `walletId` is\nset, the deposit is scoped to that sub-account.\n\n**On-chain effect:** queues a vault `deposit` message; on confirmation the\nresponse carries `transactionId` (stable logical operation anchor) and `messageId` (MQ\ncorrelation id) you can use to poll `paymentFlow.messageOutcome`.\n",
            "sdl": "mutation Deposit($input: DepositInput!) {\n  deposit(input: $input) {\n    success\n    messageId\n    transactionId\n    accountAddress\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "assetId",
                  "amount"
                ],
                "properties": {
                  "assetId": {
                    "type": "string",
                    "description": "Asset symbol (USD, EUR, GBP) or token contract id to credit."
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]+$",
                    "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  },
                  "walletId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Sub-account wallet id. Defaults to the JWT's primary wallet."
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "When true, message is routed to manual signature (user signs via UX)\ninstead of automatic execution.\n"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Deposit 1 USD (1e18 wei) into the caller's default wallet",
                  "value": {
                    "input": {
                      "assetId": "USD",
                      "amount": "1",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440000"
                    }
                  }
                },
                "with-wallet": {
                  "summary": "Deposit 500 EUR into a specific sub-account",
                  "value": {
                    "input": {
                      "assetId": "EUR",
                      "amount": "500",
                      "walletId": "WALLET-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440001"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "message",
                  "accountAddress",
                  "messageId",
                  "transactionId",
                  "signature",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "depositResult": {
                    "type": "string",
                    "nullable": true
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionId": {
                    "type": "string",
                    "description": "Stable logical operation anchor for this deposit submission."
                  },
                  "signature": {
                    "type": "string",
                    "description": "EIP-191 signature. **`x-onchain: true`.**",
                    "x-onchain": true
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Missing or invalid input field (unknown `assetId`, non-numeric `amount`, etc.)."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload from the same caller."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_deposit",
              "resource_uri": "yf://payments",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/payments.yaml#/DepositResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: DepositInput!) { deposit(input: $input) { success messageId transactionId } }\",\"variables\":{\"input\":{\"assetId\":\"USD\",\"amount\":\"1\",\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440000\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: DepositInput!) { deposit(input: $input) { success messageId transactionId } }\",\n        \"variables\": {\"input\": {\"assetId\": \"USD\", \"amount\": \"1\", \"idempotencyKey\": str(uuid.uuid4())}},\n    },\n)\nprint(resp.json()[\"data\"][\"deposit\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: DepositInput!) { deposit(input: $input) { success messageId transactionId } }`,\n  { input: { assetId: \"USD\", amount: \"1\", idempotencyKey: crypto.randomUUID() } }\n);\nconsole.log(data.deposit);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation Deposit($input: DepositInput!) {\n  deposit(input: $input) {\n    success\n    messageId\n    transactionId\n    accountAddress\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "withdraw",
                "relation": "undo"
              },
              {
                "operation": "instant",
                "relation": "next"
              },
              {
                "guide": "payment-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "instant",
            "kind": "mutation",
            "name": "instant",
            "service": "yieldfabric-payments",
            "tags": [
              "Payments"
            ],
            "summary": "Send an instant cash or credit payment from the caller's vault",
            "description": "Send funds from the caller's vault to a destination entity. Required\ninputs are `assetId` and `amount` (raw integer string at native scale).\nThe payment is **cash** by default; pass `obligor` and/or `contractId` to\nsend a **credit** payment that draws against an existing obligation.\n\nUse `destinationId` for entity-name targeting (`\"bob@yieldfabric\"`) or\n`destinationWalletId` for explicit sub-account targeting.\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4) to make retries safe —\nrepeated calls return the same payment record.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. The caller\nis taken from the JWT; when `walletId` is set, the payment is signed by\nthat sub-account.\n\n**On-chain effect:** queues a vault `send` message that locks funds on\nthe sender's side. The receiver must call `accept` to pull the funds.\nResponse carries `messageId` and `transactionId`.\n",
            "sdl": "mutation Instant($input: InstantSendInput!) {\n  instant(input: $input) {\n    success\n    messageId\n    transactionId\n    sendResult\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "assetId",
                  "amount"
                ],
                "properties": {
                  "assetId": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]+$",
                    "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                  },
                  "destinationId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Entity name / id of the recipient. Mutually exclusive with destinationWalletId."
                  },
                  "destinationWalletId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Direct recipient wallet id. Mutually exclusive with destinationId."
                  },
                  "contractId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Attach the payment to an existing contract / obligation."
                  },
                  "obligor": {
                    "type": "string",
                    "nullable": true,
                    "description": "Optional obligor entity / wallet for credit-bearing payments."
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  },
                  "walletId": {
                    "type": "string",
                    "nullable": true
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "When true, message is routed to manual signature (user signs via UX)\ninstead of automatic execution.\n"
                  }
                }
              },
              "examples": {
                "cash-payment": {
                  "summary": "Send 100 USD cash to alice@yieldfabric",
                  "value": {
                    "input": {
                      "assetId": "USD",
                      "amount": "100",
                      "destinationId": "alice@yieldfabric",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440010"
                    }
                  }
                },
                "credit-payment": {
                  "summary": "Send 500 USD against an existing obligation",
                  "value": {
                    "input": {
                      "assetId": "USD",
                      "amount": "500",
                      "destinationId": "alice@yieldfabric",
                      "contractId": "CONTRACT-OBLIGATION-12345",
                      "obligor": "bob@yieldfabric",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440011"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "message",
                  "accountAddress",
                  "destinationId",
                  "messageId",
                  "paymentId",
                  "transactionId",
                  "signature",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "destinationId": {
                    "type": "string"
                  },
                  "idHash": {
                    "type": "string",
                    "nullable": true
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "paymentId": {
                    "type": "string"
                  },
                  "sendResult": {
                    "type": "string",
                    "nullable": true
                  },
                  "transactionId": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "signature": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Missing required field, unknown destination, or invalid contract reference."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_instant",
              "resource_uri": "yf://payments",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/payments.yaml#/SendResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: InstantSendInput!) { instant(input: $input) { success messageId transactionId } }\",\"variables\":{\"input\":{\"assetId\":\"USD\",\"amount\":\"100\",\"destinationId\":\"alice@yieldfabric\",\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440010\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: InstantSendInput!) { instant(input: $input) { success messageId transactionId } }\",\n        \"variables\": {\"input\": {\"assetId\": \"USD\", \"amount\": \"100\", \"destinationId\": \"alice@yieldfabric\", \"idempotencyKey\": str(uuid.uuid4())}},\n    },\n)\nprint(resp.json()[\"data\"][\"instant\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: InstantSendInput!) { instant(input: $input) { success messageId transactionId } }`,\n  { input: { assetId: \"USD\", amount: \"100\", destinationId: \"alice@yieldfabric\", idempotencyKey: crypto.randomUUID() } }\n);\nconsole.log(data.instant);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation Instant($input: InstantSendInput!) {\n  instant(input: $input) {\n    success\n    messageId\n    transactionId\n    sendResult\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "accept",
                "relation": "next"
              },
              {
                "operation": "deposit",
                "relation": "prerequisite"
              },
              {
                "operation": "createDistribution",
                "relation": "alternative"
              },
              {
                "guide": "payment-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "accept",
            "kind": "mutation",
            "name": "accept",
            "service": "yieldfabric-payments",
            "tags": [
              "Payments"
            ],
            "summary": "Accept a pending payment to claim locked funds",
            "description": "Payee claims a payment that was locked on the sender's side by `instant`\nor `createDistribution`. The only required input is `paymentId`; the\ncaller is identified from the JWT and must be the payment's receiver.\n\nPass `amount` to do a partial retrieval (only relevant for linearly\nvesting payments). Omit it to claim the full available balance.\n\n**Idempotency:** acceptance is keyed server-side to the selected chain and\ncurrent payment generation. `idempotencyKey` remains an accepted\ncompatibility field, but it does not create a second acceptance identity.\nDirect requests, automation, replicas, and restart recovery therefore\nconverge through one short atomic transaction-anchor intent claim. Once\nestablished, request-level cleanup never deletes the claim because another\nreplica may already be resuming it; the same actor/purpose retries the\ndeterministic submission while the opposing purpose remains excluded. If\nautomation already accepted the same payment, an authorized payee receives\n`ALREADY_SATISFIED` with the original retrieve's canonical `messageId`, and\nno second chain operation is submitted. `IN_FLIGHT` likewise reuses the real\nexisting message.\n\nIf MQ returns an idempotency conflict or submission verification is\nambiguous, the resolver preserves the unbound intent and returns the\ncanonical or potentially canonical `messageId` in the error extensions. An\nerror extension alone never binds the transaction anchor to MQ; binding is\none-way and occurs only after the stored message's immutable chain, type,\npayload, wallet, and idempotency identity have been verified. Poll that\n`messageId` and retry the same acceptance to reconcile it; changing the\ncompatibility `idempotencyKey` cannot create a second acceptance identity.\n\nIf that canonical `Retrieve` message records a failed chain execution, a later `accept`\ndoes not allocate a replacement claim. Wait for failure post-processing,\ncorrect the transient condition, then `POST\n/api/users/{user_id}/messages/{messageId}/retry` to redrive the same message\nautomatically and rebuild its validation/proof from current state. Manual\nfailures require a corrected fresh command/signature. If chain execution\nalready succeeded and only finalize/outbox/graph processing failed, use\npost-processing recovery instead; the chain transaction must not be repeated.\nOther message types and validation-only/direct-relay failures require a corrected fresh submission.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. When\n`walletId` is set, accept is performed by that sub-account (the\nsame one that's the on-chain receiver).\n\n**On-chain effect:** queues a vault `accept` message; on confirmation\nfunds move from the sender's locked balance into the payee's vault.\nResponse carries `disposition`, `messageId`, and `transactionId`.\n",
            "sdl": "mutation Accept($input: AcceptInput!) {\n  accept(input: $input) {\n    success\n    disposition\n    messageId\n    transactionId\n    acceptResult\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "paymentId"
                ],
                "properties": {
                  "paymentId": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]+$",
                    "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                  },
                  "walletId": {
                    "type": "string",
                    "nullable": true
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true,
                    "description": "Compatibility field. Accept idempotency is derived server-side from\nthe selected chain and current payment generation, so changing this\nvalue cannot create a second acceptance identity.\n"
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "When true, message is routed to manual signature (user signs via UX)\ninstead of automatic execution.\n"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Accept the full pending balance on a payment",
                  "value": {
                    "input": {
                      "paymentId": "PAYMENT-7c4a1d8e-3b9d-4c10-9f8e-1a2b3c4d5e6f"
                    }
                  }
                },
                "partial-vesting": {
                  "summary": "Accept only 250 units of a linearly vesting payment",
                  "value": {
                    "input": {
                      "paymentId": "PAYMENT-7c4a1d8e-3b9d-4c10-9f8e-1a2b3c4d5e6f",
                      "amount": "250",
                      "walletId": "WALLET-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "disposition",
                  "message",
                  "accountAddress",
                  "messageId",
                  "transactionId",
                  "signature",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "disposition": {
                    "type": "string",
                    "enum": [
                      "SUBMITTED",
                      "IN_FLIGHT",
                      "ALREADY_SATISFIED"
                    ],
                    "description": "Whether this call queued a new retrieve, reused a retrieve already in flight, or verified that the payment had already reached COMPLETED. Every disposition returns the real canonical MQ messageId; no caller should synthesize a correlation id."
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "idHash": {
                    "type": "string",
                    "nullable": true
                  },
                  "acceptResult": {
                    "type": "string",
                    "nullable": true
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionId": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "signature": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Unknown `paymentId`, partial `amount` exceeds vested balance, etc."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "FORBIDDEN",
                "status": 403,
                "description": "Caller is not the payment's receiver."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "The deterministic retrieve key resolved to a canonical MQ message with a different immutable envelope. The unbound acceptance intent and returned `messageId` are preserved for reconciliation; changing the compatibility `idempotencyKey` does not bypass the claim."
              },
              {
                "code": "SUBMISSION_OUTCOME_UNKNOWN",
                "status": 503,
                "description": "MQ returned a message ID, but canonical immutable-envelope verification did not complete. The operation may execute; poll the returned `messageId` and retry this same acceptance to reconcile it."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_accept",
              "resource_uri": "yf://payments",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/payments.yaml#/AcceptResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: AcceptInput!) { accept(input: $input) { success disposition messageId transactionId } }\",\"variables\":{\"input\":{\"paymentId\":\"PAYMENT-7c4a1d8e-3b9d-4c10-9f8e-1a2b3c4d5e6f\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: AcceptInput!) { accept(input: $input) { success disposition messageId transactionId } }\",\n        \"variables\": {\"input\": {\"paymentId\": \"PAYMENT-7c4a1d8e-3b9d-4c10-9f8e-1a2b3c4d5e6f\"}},\n    },\n)\nprint(resp.json()[\"data\"][\"accept\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: AcceptInput!) { accept(input: $input) { success disposition messageId transactionId } }`,\n  { input: { paymentId: \"PAYMENT-7c4a1d8e-3b9d-4c10-9f8e-1a2b3c4d5e6f\" } }\n);\nconsole.log(data.accept);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation Accept($input: AcceptInput!) {\n  accept(input: $input) {\n    success\n    disposition\n    messageId\n    transactionId\n    acceptResult\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "instant",
                "relation": "prerequisite"
              },
              {
                "operation": "acceptAll",
                "relation": "alternative"
              },
              {
                "operation": "createDistribution",
                "relation": "prerequisite"
              },
              {
                "guide": "payment-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "acceptAll",
            "kind": "mutation",
            "name": "acceptAll",
            "service": "yieldfabric-payments",
            "tags": [
              "Payments"
            ],
            "summary": "Accept every claimable payment in a denomination in one batch",
            "description": "Sweeps every pending payment in `denomination` that the caller can claim,\nsigning one accept per payment. The only required input is `denomination`\n(e.g. `\"USD\"`).\n\nPass `obligor` to restrict the sweep to payments backed by a specific\nobligor (useful when accepting just one loan's coupons). Pass `walletId`\nto scope the sweep to a single sub-account so that account signs every\naccept.\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4) to make retries safe;\nthe same key returns the same `acceptedPayments` set.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`.\n\n**On-chain effect:** one queued message per claimable payment. Response\ncarries per-payment `messageId`/`transactionId` plus `acceptedCount` and\n`failedCount` aggregates.\n",
            "sdl": "mutation AcceptAll($input: AcceptAllInput!) {\n  acceptAll(input: $input) {\n    success\n    totalPayments\n    acceptedCount\n    failedCount\n    acceptedPayments { paymentId messageId transactionId }\n    failedPayments { paymentId error }\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "denomination"
                ],
                "properties": {
                  "denomination": {
                    "type": "string",
                    "description": "Asset denomination to filter PENDING payables on."
                  },
                  "obligor": {
                    "type": "string",
                    "nullable": true,
                    "description": "Optional obligor filter — only accept payables from this obligor."
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  },
                  "walletId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Optional. When set, only accept payables where the payee (receiver)\nis this specific wallet. Ensures accept_all is scoped to a single\naccount (e.g. loan account) and signs as that wallet.\n"
                  }
                }
              },
              "examples": {
                "sweep-usd": {
                  "summary": "Accept every claimable USD payment for the caller's default wallet",
                  "value": {
                    "input": {
                      "denomination": "USD",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440030"
                    }
                  }
                },
                "sweep-loan-coupons": {
                  "summary": "Accept only the coupons backed by a specific obligor into a loan account",
                  "value": {
                    "input": {
                      "denomination": "USD",
                      "obligor": "borrower-co@yieldfabric",
                      "walletId": "WALLET-loan-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440031"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "message",
                  "totalPayments",
                  "acceptedCount",
                  "failedCount",
                  "acceptedPayments",
                  "failedPayments",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "totalPayments": {
                    "type": "integer"
                  },
                  "acceptedCount": {
                    "type": "integer"
                  },
                  "failedCount": {
                    "type": "integer"
                  },
                  "acceptedPayments": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "paymentId",
                        "amount",
                        "messageId",
                        "transactionId"
                      ],
                      "properties": {
                        "paymentId": {
                          "type": "string"
                        },
                        "amount": {
                          "type": "integer"
                        },
                        "messageId": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "transactionId": {
                          "type": "string",
                          "x-onchain": true
                        }
                      }
                    }
                  },
                  "failedPayments": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "paymentId",
                        "amount",
                        "error"
                      ],
                      "properties": {
                        "paymentId": {
                          "type": "string"
                        },
                        "amount": {
                          "type": "integer"
                        },
                        "error": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "timestamp": {
                    "type": "string"
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Unknown `denomination` or unknown `obligor`."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_acceptAll",
              "resource_uri": "yf://payments",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/payments.yaml#/AcceptAllResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: AcceptAllInput!) { acceptAll(input: $input) { success acceptedCount failedCount acceptedPayments { paymentId transactionId } } }\",\"variables\":{\"input\":{\"denomination\":\"USD\",\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440030\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: AcceptAllInput!) { acceptAll(input: $input) { success acceptedCount failedCount } }\",\n        \"variables\": {\"input\": {\"denomination\": \"USD\", \"idempotencyKey\": str(uuid.uuid4())}},\n    },\n)\nprint(resp.json()[\"data\"][\"acceptAll\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: AcceptAllInput!) { acceptAll(input: $input) { success acceptedCount failedCount acceptedPayments { paymentId transactionId } } }`,\n  { input: { denomination: \"USD\", idempotencyKey: crypto.randomUUID() } }\n);\nconsole.log(data.acceptAll);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation AcceptAll($input: AcceptAllInput!) {\n  acceptAll(input: $input) {\n    success\n    totalPayments\n    acceptedCount\n    failedCount\n    acceptedPayments { paymentId messageId transactionId }\n    failedPayments { paymentId error }\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "accept",
                "relation": "alternative"
              },
              {
                "operation": "instant",
                "relation": "prerequisite"
              },
              {
                "guide": "payment-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "withdraw",
            "kind": "mutation",
            "name": "withdraw",
            "service": "yieldfabric-payments",
            "tags": [
              "Payments"
            ],
            "summary": "Withdraw an asset from the caller's vault",
            "description": "Pull funds out of the caller's on-chain vault for the named `assetId`.\nRequired inputs are `assetId` (e.g. `\"USD\"`) and `amount` (raw integer\nstring at native scale, typically 1e18).\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4) to make retries safe —\nrepeated calls return the original result without double-spending.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. When\n`walletId` is set, the withdrawal is scoped to that sub-account.\n\n**On-chain effect:** queues a vault `withdraw` message; on confirmation\nthe response carries `transactionId` (stable logical operation anchor) and `messageId`\n(MQ correlation id).\n",
            "sdl": "mutation Withdraw($input: WithdrawInput!) {\n  withdraw(input: $input) {\n    success\n    messageId\n    transactionId\n    accountAddress\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "assetId",
                  "amount"
                ],
                "properties": {
                  "assetId": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]+$",
                    "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  },
                  "walletId": {
                    "type": "string",
                    "nullable": true
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "When true, message is routed to manual signature (user signs via UX)\ninstead of automatic execution.\n"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Withdraw 1 USD (1e18 wei) from the caller's default wallet",
                  "value": {
                    "input": {
                      "assetId": "USD",
                      "amount": "1",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440040"
                    }
                  }
                },
                "with-wallet": {
                  "summary": "Withdraw 200 GBP from a specific sub-account",
                  "value": {
                    "input": {
                      "assetId": "GBP",
                      "amount": "200",
                      "walletId": "WALLET-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440041"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "message",
                  "accountAddress",
                  "messageId",
                  "transactionId",
                  "signature",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "withdrawResult": {
                    "type": "string",
                    "nullable": true
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionId": {
                    "type": "string",
                    "description": "Stable logical operation anchor for this withdrawal submission."
                  },
                  "signature": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Unknown `assetId` or amount exceeds vault balance."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_withdraw",
              "resource_uri": "yf://payments",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/payments.yaml#/WithdrawResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: WithdrawInput!) { withdraw(input: $input) { success messageId transactionId } }\",\"variables\":{\"input\":{\"assetId\":\"USD\",\"amount\":\"1\",\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440040\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: WithdrawInput!) { withdraw(input: $input) { success messageId transactionId } }\",\n        \"variables\": {\"input\": {\"assetId\": \"USD\", \"amount\": \"1\", \"idempotencyKey\": str(uuid.uuid4())}},\n    },\n)\nprint(resp.json()[\"data\"][\"withdraw\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: WithdrawInput!) { withdraw(input: $input) { success messageId transactionId } }`,\n  { input: { assetId: \"USD\", amount: \"1\", idempotencyKey: crypto.randomUUID() } }\n);\nconsole.log(data.withdraw);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation Withdraw($input: WithdrawInput!) {\n  withdraw(input: $input) {\n    success\n    messageId\n    transactionId\n    accountAddress\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "deposit",
                "relation": "undo"
              },
              {
                "guide": "payment-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "createDistribution",
            "kind": "mutation",
            "name": "createDistribution",
            "service": "yieldfabric-payments",
            "tags": [
              "Payments"
            ],
            "summary": "Create a one-to-many distribution with multiple recipients",
            "description": "Create a single DISTRIBUTION contract with one RECEIVABLE per recipient.\nRequired inputs are `assetId` and `recipients` (each carrying `address`\nand `amount`). Each recipient claims their share via the standard\n`accept` mutation referencing the per-recipient `paymentId`.\n\nPass `obligor` to back the distribution against a specific obligor\n(defaults to the sender). Use a recipient's `obligationId` to scope a\nshare to an obligation token id rather than a wallet address.\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4) to make retries safe.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. When\n`walletId` is set, the distribution is signed by that sub-account.\n\n**On-chain effect:** queues a vault `create_distribution` message that\nlocks the total amount on the sender's side. Response carries\n`messageId`, `transactionId`, and the distribution-id hash. The sender\ncan cancel the distribution only if **no recipient** has claimed yet.\n",
            "sdl": "mutation CreateDistribution($input: CreateDistributionInput!) {\n  createDistribution(input: $input) {\n    success\n    messageId\n    transactionId\n    idHash\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "assetId",
                  "recipients"
                ],
                "properties": {
                  "assetId": {
                    "type": "string"
                  },
                  "obligor": {
                    "type": "string",
                    "nullable": true,
                    "description": "Entity name or ID of the obligor (payer). Optional; defaults to sender."
                  },
                  "recipients": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "description": "One recipient for a distribution: (address, optional obligation_id, amount).\n",
                      "required": [
                        "address",
                        "amount"
                      ],
                      "properties": {
                        "address": {
                          "type": "string"
                        },
                        "obligationId": {
                          "type": "string",
                          "nullable": true,
                          "description": "`\"0\"` or omit = wallet; non-zero = NFT token id\n(claimant = `ownerOf(address, obligation_id)`).\n"
                        },
                        "amount": {
                          "type": "string",
                          "pattern": "^[0-9]+$",
                          "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                        }
                      }
                    }
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  },
                  "walletId": {
                    "type": "string",
                    "nullable": true
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "When true, message is routed to manual signature (user signs via UX)\ninstead of automatic execution.\n"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Split 300 USD evenly across three recipients",
                  "value": {
                    "input": {
                      "assetId": "USD",
                      "recipients": [
                        {
                          "address": "alice@yieldfabric",
                          "amount": "100"
                        },
                        {
                          "address": "bob@yieldfabric",
                          "amount": "100"
                        },
                        {
                          "address": "carol@yieldfabric",
                          "amount": "100"
                        }
                      ],
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440050"
                    }
                  }
                },
                "with-obligor": {
                  "summary": "Coupon distribution backed by an obligor entity",
                  "value": {
                    "input": {
                      "assetId": "USD",
                      "obligor": "borrower-co@yieldfabric",
                      "recipients": [
                        {
                          "address": "lender1@yieldfabric",
                          "amount": "1500"
                        },
                        {
                          "address": "lender2@yieldfabric",
                          "amount": "500"
                        }
                      ],
                      "walletId": "WALLET-coupons-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440051"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "message",
                  "accountAddress",
                  "messageId",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "idHash": {
                    "type": "string",
                    "nullable": true
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionId": {
                    "type": "string",
                    "nullable": true,
                    "x-onchain": true
                  },
                  "signature": {
                    "type": "string",
                    "nullable": true,
                    "x-onchain": true
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Empty recipients list, unknown asset, or recipient address fails resolution."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_createDistribution",
              "resource_uri": "yf://payments",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/payments.yaml#/CreateDistributionResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: CreateDistributionInput!) { createDistribution(input: $input) { success messageId transactionId idHash } }\",\"variables\":{\"input\":{\"assetId\":\"USD\",\"recipients\":[{\"address\":\"alice@yieldfabric\",\"amount\":\"100\"},{\"address\":\"bob@yieldfabric\",\"amount\":\"100\"}],\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440050\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: CreateDistributionInput!) { createDistribution(input: $input) { success messageId transactionId idHash } }\",\n        \"variables\": {\n            \"input\": {\n                \"assetId\": \"USD\",\n                \"recipients\": [\n                    {\"address\": \"alice@yieldfabric\", \"amount\": \"100\"},\n                    {\"address\": \"bob@yieldfabric\", \"amount\": \"100\"},\n                ],\n                \"idempotencyKey\": str(uuid.uuid4()),\n            }\n        },\n    },\n)\nprint(resp.json()[\"data\"][\"createDistribution\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: CreateDistributionInput!) { createDistribution(input: $input) { success messageId transactionId idHash } }`,\n  {\n    input: {\n      assetId: \"USD\",\n      recipients: [\n        { address: \"alice@yieldfabric\", amount: \"100\" },\n        { address: \"bob@yieldfabric\", amount: \"100\" },\n      ],\n      idempotencyKey: crypto.randomUUID(),\n    },\n  }\n);\nconsole.log(data.createDistribution);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation CreateDistribution($input: CreateDistributionInput!) {\n  createDistribution(input: $input) {\n    success\n    messageId\n    transactionId\n    idHash\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "accept",
                "relation": "next"
              },
              {
                "operation": "instant",
                "relation": "alternative"
              },
              {
                "guide": "payment-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "createObligation",
            "kind": "mutation",
            "name": "createObligation",
            "service": "yieldfabric-payments",
            "tags": [
              "Obligations"
            ],
            "summary": "Create an obligation contract (payment commitment or agreement-only)",
            "description": "Create a new obligation contract between an obligor (payer) and a\ncounterpart (payee). Mints an obligation NFT on chain, generates a\nunique `contractId`, and writes the obligation metadata\n(`counterpart`, `obligor`, `denomination`, `expiry`).\n\n**Two shapes are supported:**\n\n- **Payment obligation** (`cash-obligation` / `third-party-obligation`\n  examples below) — includes `denomination` and `initialPayments`\n  (the amount lives in `initialPayments.amount`). Used for loans,\n  invoices, coupons, scheduled transfers.\n- **Agreement-only obligation** (`terms-acceptance` example below) —\n  omits `denomination` and `initialPayments`. Carries the\n  agreement text or its content hash in `data`. The counterpart's\n  `acceptObligation` writes a tamper-evident on-chain acceptance record.\n  Used for terms of service, NDAs, KYC consent capture, privacy-policy\n  acknowledgment, or any \"user must explicitly accept this binding text\"\n  use case. See the\n  [Agreement-only obligations](../../guides/obligation-lifecycle.md#agreement-only-obligations-no-payments)\n  section of the lifecycle guide.\n\nThe `obligor` defaults to the caller; pass it explicitly for\nthird-party-issued obligations. `data` is free-form JSON for schedule,\nvesting, oracle hooks, or agreement metadata.\n\n**Field requirements:** `counterpart` (or `counterpartWalletId`) is\nalways required. `denomination` is required *only* when `initialPayments`\nis present; omit it for agreement-only contracts. `obligor` and\n`initialPayments` are both optional.\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4) to make retries safe.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. When\n`obligorWalletId` is set, the obligation is signed by that sub-account.\n\n**State transition:** `(none) → ACTIVE` (pending acceptance). The\ncounterpart must call `acceptObligation` before the expiry to lock in\nthe obligation; otherwise it expires.\n\n**On-chain effect:** queues a vault `create_obligation` message. On\nconfirmation the response carries `contractId` (e.g.\n`CONTRACT-OBLIGATION-12345`), `messageId`, and `transactionId`.\n",
            "sdl": "mutation CreateObligation($input: CreateObligationInput!) {\n  createObligation(input: $input) {\n    success\n    contractId\n    messageId\n    transactionId\n    idHash\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "properties": {
                  "counterpart": {
                    "type": "string",
                    "nullable": true,
                    "description": "Entity name (e.g. `\"alice@yieldfabric\"`). Mutually exclusive with counterpartWalletId."
                  },
                  "counterpartWalletId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Direct wallet id of the counterpart. Mutually exclusive with counterpart."
                  },
                  "obligationAddress": {
                    "type": "string",
                    "nullable": true,
                    "description": "Address of the `ConfidentialObligation` proxy to mint into.\n\nConfidentialObligation is deployed per-class via the\n`ConfidentialObligationFactory` (EIP-1167 minimal proxies), so a\nsingle chain can have many obligation classes — each with its own\n`class_owner`, mint mode, and (optionally) identity registry. Pass\nthe proxy address returned by `deployObligation` /\n`myObligationClasses` to mint into a specific class.\n\nWhen omitted, the validation phase falls back to the chain default\n(`chain_registry().contracts.obligation`) — the bootstrap class\nevery chain ships with. The downstream `acceptObligation` /\n`transferObligation` / `cancelObligation` flows auto-resolve the\nper-class address from the `Token.address` stored at mint time, so\ncallers don't need to thread `obligationAddress` through the\naccept/transfer/cancel inputs.\n"
                  },
                  "denomination": {
                    "type": "string",
                    "nullable": true,
                    "description": "Asset symbol (USD, EUR, AUD) or token id the payment amount is denominated in.\n\n**Conditionally required.** Required when `initialPayments` is\npresent — the server rejects the request otherwise with\n`\"denomination is required when initial_payments are provided\"`.\n\n**Omit for agreement-only obligations** (terms of service, NDAs,\nconsent records) that carry no payment schedule. See the\n[Agreement-only obligations](../../guides/obligation-lifecycle.md#agreement-only-obligations-no-payments)\nsection of the lifecycle guide.\n"
                  },
                  "obligor": {
                    "type": "string",
                    "nullable": true,
                    "description": "Entity name of the obligor (payer). Defaults to caller."
                  },
                  "obligorWalletId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Direct obligor sub-account wallet id. Mutually exclusive with obligor."
                  },
                  "expiry": {
                    "type": "string",
                    "nullable": true,
                    "description": "Unix timestamp (string) or ISO-8601 date string."
                  },
                  "data": {
                    "description": "Arbitrary JSON value (object, array, scalar, or null)."
                  },
                  "initialPayments": {
                    "type": "object",
                    "required": [
                      "amount",
                      "payments"
                    ],
                    "properties": {
                      "amount": {
                        "type": "string",
                        "pattern": "^[0-9]+$",
                        "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                      },
                      "denomination": {
                        "type": "string",
                        "nullable": true
                      },
                      "obligor": {
                        "type": "string",
                        "nullable": true
                      },
                      "payments": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "description": "Shared input type for vault payment data. Used by both contract and swap\nflows to avoid duplication.\n",
                          "properties": {
                            "oracleAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleOwner": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeySender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSenderSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeyRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipientSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockReceiver": {
                              "type": "string",
                              "nullable": true
                            },
                            "linearVesting": {
                              "type": "boolean",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  },
                  "contractId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Override the generated contract id. Rarely used."
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "When true, message is routed to manual signature (user signs via UX)\ninstead of automatic execution.\n"
                  }
                }
              },
              "examples": {
                "cash-obligation": {
                  "summary": "Issue a 5000 USD cash obligation due in 30 days",
                  "value": {
                    "input": {
                      "counterpart": "alice@yieldfabric",
                      "denomination": "USD",
                      "expiry": "1735603200",
                      "initialPayments": {
                        "amount": "5000",
                        "payments": [
                          {
                            "unlockSender": "1735603200",
                            "unlockReceiver": "1735603200"
                          }
                        ]
                      },
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440100"
                    }
                  }
                },
                "third-party-obligation": {
                  "summary": "Issue an obligation where caller acts on behalf of a third-party obligor",
                  "value": {
                    "input": {
                      "counterpart": "lender@yieldfabric",
                      "obligor": "borrower-co@yieldfabric",
                      "obligorWalletId": "WALLET-borrower-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f",
                      "denomination": "USD",
                      "expiry": "1767139200",
                      "initialPayments": {
                        "amount": "1000000",
                        "payments": [
                          {
                            "unlockSender": "1767139200",
                            "unlockReceiver": "1767139200"
                          }
                        ]
                      },
                      "data": {
                        "schedule": "bullet",
                        "coupon_bps": 500
                      },
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440101"
                    }
                  }
                },
                "terms-acceptance": {
                  "summary": "Agreement-only obligation (no payment terms). The counterparty's\non-chain `acceptObligation` produces a tamper-evident acceptance\nrecord. Use for terms of service, NDAs, consent capture, etc.\nOmits `denomination`, `obligor`, and `initialPayments`;\nthe agreement body or its hash lives in `data`.\n",
                  "value": {
                    "input": {
                      "counterpart": "alice@yieldfabric",
                      "expiry": "1735603200",
                      "data": {
                        "kind": "terms_and_conditions",
                        "version": "v1.2",
                        "title": "Service Agreement",
                        "body_uri": "ipfs://QmExampleHash",
                        "body_sha256": "abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789",
                        "jurisdiction": "NSW"
                      },
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440102"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "message",
                  "accountAddress",
                  "messageId",
                  "contractId",
                  "transactionId",
                  "signature",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "obligationResult": {
                    "type": "string",
                    "nullable": true
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "contractId": {
                    "type": "string",
                    "description": "Generated contract id (`CONTRACT-<uuid>` form)."
                  },
                  "transactionId": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "signature": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "idHash": {
                    "type": "string",
                    "nullable": true
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Missing required field, unknown counterpart, invalid expiry, etc."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_createObligation",
              "resource_uri": "yf://obligations",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/obligations.yaml#/CreateObligationResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: CreateObligationInput!) { createObligation(input: $input) { success contractId messageId transactionId } }\",\"variables\":{\"input\":{\"counterpart\":\"alice@yieldfabric\",\"denomination\":\"USD\",\"expiry\":\"1735603200\",\"initialPayments\":{\"amount\":\"5000\",\"payments\":[{\"unlockSender\":\"1735603200\",\"unlockReceiver\":\"1735603200\"}]},\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440100\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: CreateObligationInput!) { createObligation(input: $input) { success contractId messageId transactionId } }\",\n        \"variables\": {\n            \"input\": {\n                \"counterpart\": \"alice@yieldfabric\",\n                \"denomination\": \"USD\",\n                \"expiry\": \"1735603200\",\n                \"initialPayments\": {\n                    \"amount\": \"5000\",\n                    \"payments\": [{\"unlockSender\": \"1735603200\", \"unlockReceiver\": \"1735603200\"}],\n                },\n                \"idempotencyKey\": str(uuid.uuid4()),\n            }\n        },\n    },\n)\nprint(resp.json()[\"data\"][\"createObligation\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: CreateObligationInput!) { createObligation(input: $input) { success contractId messageId transactionId } }`,\n  {\n    input: {\n      counterpart: \"alice@yieldfabric\",\n      denomination: \"USD\",\n      expiry: \"1735603200\",\n      initialPayments: {\n        amount: \"5000\",\n        payments: [{ unlockSender: \"1735603200\", unlockReceiver: \"1735603200\" }],\n      },\n      idempotencyKey: crypto.randomUUID(),\n    },\n  }\n);\nconsole.log(data.createObligation);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation CreateObligation($input: CreateObligationInput!) {\n  createObligation(input: $input) {\n    success\n    contractId\n    messageId\n    transactionId\n    idHash\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "acceptObligation",
                "relation": "next"
              },
              {
                "operation": "transferObligation",
                "relation": "next"
              },
              {
                "operation": "cancelObligation",
                "relation": "undo"
              },
              {
                "guide": "obligation-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "acceptObligation",
            "kind": "mutation",
            "name": "acceptObligation",
            "service": "yieldfabric-payments",
            "tags": [
              "Obligations"
            ],
            "summary": "Counterpart accepts an obligation to lock in its payment schedule",
            "description": "Counterpart accepts a pending obligation, committing to the payment\nschedule encoded in the contract. Acceptance must happen within the\nacceptance window (before the obligation's `expiry`); after that the\noffer is invalidated.\n\nPass either `contractId` (single obligation) or `contractReference`\n(unified — supports single or composed contracts). Both shapes are\naccepted; `contractReference` is the forward-looking field.\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4) to make retries safe.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. The\ncaller must be the contract's `counterpart`. When `walletId` is set,\nthe same sub-account that's the on-chain counterpart signs the accept.\n\n**State transition:** `ACTIVE → COMPLETED`. From here individual payments\nbegin executing on their own schedules. There is no intermediate\n`ACCEPTED` state on the `ContractStatus` enum — acceptance moves\ndirectly to `COMPLETED`.\n\n**On-chain effect:** queues a vault `accept_obligation` message. Response\ncarries `obligationId`, `messageId`, and `transactionId`.\n",
            "sdl": "mutation AcceptObligation($input: AcceptObligationInput!) {\n  acceptObligation(input: $input) {\n    success\n    obligationId\n    messageId\n    transactionId\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "description": "Per-class routing is automatic. The resolver looks up the\n`Token.address` row written by the mint and threads that\n`ConfidentialObligation` proxy through to the meta-tx target —\ncallers don't pass `obligationAddress` here. See\n[obligation-lifecycle.md → Class proxies](../guides/obligation-lifecycle.md)\nif you need the conceptual background on EIP-1167 obligation classes.\n",
                "type": "object",
                "properties": {
                  "contractId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Legacy field — kept for backward compatibility. If provided, will be\nconverted to ContractReference internally.\n"
                  },
                  "contractReference": {
                    "type": "object",
                    "description": "Unified contract reference — can be either single contract or composed contract.\nExactly one of contractId or composedContractId must be provided.\n",
                    "properties": {
                      "contractId": {
                        "type": "string",
                        "nullable": true,
                        "description": "Single contract ID (mutually exclusive with composedContractId)."
                      },
                      "composedContractId": {
                        "type": "string",
                        "nullable": true,
                        "description": "Composed contract ID (mutually exclusive with contractId)."
                      }
                    }
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  },
                  "walletId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Optional wallet ID (obligor sub-account). When set, accept is\nperformed as this wallet so the same sub-account that issued can\naccept.\n"
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "When true, message is routed to manual signature (user signs via UX)\ninstead of automatic execution.\n"
                  }
                }
              },
              "examples": {
                "by-contract-id": {
                  "summary": "Accept a single obligation by contract id",
                  "value": {
                    "input": {
                      "contractId": "CONTRACT-OBLIGATION-12345",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440110"
                    }
                  }
                },
                "by-reference": {
                  "summary": "Accept using the unified ContractReference (single or composed)",
                  "value": {
                    "input": {
                      "contractReference": {
                        "contractId": "CONTRACT-OBLIGATION-12345"
                      },
                      "walletId": "WALLET-counterpart-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440111"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "message",
                  "accountAddress",
                  "obligationId",
                  "messageId",
                  "transactionId",
                  "signature",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "obligationId": {
                    "type": "string"
                  },
                  "acceptResult": {
                    "type": "string",
                    "nullable": true
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionId": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "signature": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "contractIds": {
                    "type": "array",
                    "nullable": true,
                    "description": "All contract IDs that were accepted (for composed contracts).",
                    "items": {
                      "type": "string"
                    }
                  },
                  "composedContractId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Composed contract ID if this was a composed contract accept."
                  },
                  "composedId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Composed operation ID from composed_flow (if used)."
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Unknown contract, expired obligation, or both `contractId` and `contractReference` omitted."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "FORBIDDEN",
                "status": 403,
                "description": "Caller is not the obligation's `counterpart`."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_acceptObligation",
              "resource_uri": "yf://obligations",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/obligations.yaml#/AcceptObligationResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: AcceptObligationInput!) { acceptObligation(input: $input) { success obligationId messageId transactionId } }\",\"variables\":{\"input\":{\"contractId\":\"CONTRACT-OBLIGATION-12345\",\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440110\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: AcceptObligationInput!) { acceptObligation(input: $input) { success obligationId messageId transactionId } }\",\n        \"variables\": {\"input\": {\"contractId\": \"CONTRACT-OBLIGATION-12345\", \"idempotencyKey\": str(uuid.uuid4())}},\n    },\n)\nprint(resp.json()[\"data\"][\"acceptObligation\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: AcceptObligationInput!) { acceptObligation(input: $input) { success obligationId messageId transactionId } }`,\n  { input: { contractId: \"CONTRACT-OBLIGATION-12345\", idempotencyKey: crypto.randomUUID() } }\n);\nconsole.log(data.acceptObligation);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation AcceptObligation($input: AcceptObligationInput!) {\n  acceptObligation(input: $input) {\n    success\n    obligationId\n    messageId\n    transactionId\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "createObligation",
                "relation": "prerequisite"
              },
              {
                "operation": "transferObligation",
                "relation": "next"
              },
              {
                "operation": "cancelObligation",
                "relation": "alternative"
              },
              {
                "guide": "obligation-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "transferObligation",
            "kind": "mutation",
            "name": "transferObligation",
            "service": "yieldfabric-payments",
            "tags": [
              "Obligations"
            ],
            "summary": "Transfer an obligation to a new holder",
            "description": "Transfer ownership of an obligation NFT (and therefore its payment\nrights) from the current holder to `destinationId`. The new holder\nbecomes the on-chain `ownerOf(tokenId)` and starts receiving the\nobligation's RECEIVABLEs.\n\nPass either `contractId` (single obligation) or `contractReference`\n(unified — supports composed contracts; all sub-obligations are\ntransferred together). At least one of `destinationId` (entity name)\nor `destinationWalletId` (explicit sub-account) must be set.\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4) to make retries safe.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. The\ncaller must be the current `ownerOf(tokenId)`.\n\n**On-chain effect:** queues a `transfer_obligation` message; on\nconfirmation the NFT is reassigned and the response carries the new\n`destinationAddress`, `transactionId`, and the full list of `contractIds`\nthat moved (multiple entries for composed bundles).\n",
            "sdl": "mutation TransferObligation($input: TransferObligationInput!) {\n  transferObligation(input: $input) {\n    success\n    obligationId\n    destinationId\n    destinationAddress\n    messageId\n    transactionId\n    contractIds\n    composedContractId\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "description": "Per-class routing is automatic — see `AcceptObligationInput`. The\nresolver pulls the holding `ConfidentialObligation` proxy address\nfrom the `Token` row and routes the meta-tx accordingly.\n",
                "type": "object",
                "properties": {
                  "contractId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Legacy field — kept for backward compatibility. If provided, will be\nconverted to ContractReference internally.\n"
                  },
                  "contractReference": {
                    "type": "object",
                    "description": "Unified contract reference — can be either single contract or composed contract.\nExactly one of contractId or composedContractId must be provided.\n",
                    "properties": {
                      "contractId": {
                        "type": "string",
                        "nullable": true,
                        "description": "Single contract ID (mutually exclusive with composedContractId)."
                      },
                      "composedContractId": {
                        "type": "string",
                        "nullable": true,
                        "description": "Composed contract ID (mutually exclusive with contractId)."
                      }
                    }
                  },
                  "destinationId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Recipient entity name / id. Mutually exclusive with destinationWalletId."
                  },
                  "destinationWalletId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Recipient wallet id. Mutually exclusive with destinationId."
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "When true, message is routed to manual signature (user signs via UX)\ninstead of automatic execution.\n"
                  }
                }
              },
              "examples": {
                "by-contract-id": {
                  "summary": "Transfer a single obligation to a new entity",
                  "value": {
                    "input": {
                      "contractId": "CONTRACT-OBLIGATION-12345",
                      "destinationId": "newholder@yieldfabric",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440120"
                    }
                  }
                },
                "composed-to-wallet": {
                  "summary": "Transfer a composed-contract bundle to a specific sub-account",
                  "value": {
                    "input": {
                      "contractReference": {
                        "composedContractId": "COMPOSED-CONTRACT-987654"
                      },
                      "destinationWalletId": "WALLET-buyer-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440121"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "message",
                  "accountAddress",
                  "obligationId",
                  "destinationId",
                  "destinationAddress",
                  "messageId",
                  "transactionId",
                  "signature",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "obligationId": {
                    "type": "string"
                  },
                  "destinationId": {
                    "type": "string"
                  },
                  "destinationAddress": {
                    "type": "string"
                  },
                  "transferResult": {
                    "type": "string",
                    "nullable": true
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionId": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "signature": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "contractIds": {
                    "type": "array",
                    "nullable": true,
                    "description": "All contract IDs that were transferred (for composed contracts).",
                    "items": {
                      "type": "string"
                    }
                  },
                  "composedContractId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Composed contract ID if this was a composed contract transfer."
                  },
                  "composedId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Composed operation ID from composed_flow (if used)."
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Unknown contract, missing destination, or both contract refs omitted."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "FORBIDDEN",
                "status": 403,
                "description": "Caller is not the obligation's current owner."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_transferObligation",
              "resource_uri": "yf://obligations",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/obligations.yaml#/TransferObligationResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: TransferObligationInput!) { transferObligation(input: $input) { success obligationId destinationAddress messageId transactionId } }\",\"variables\":{\"input\":{\"contractId\":\"CONTRACT-OBLIGATION-12345\",\"destinationId\":\"newholder@yieldfabric\",\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440120\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: TransferObligationInput!) { transferObligation(input: $input) { success obligationId destinationAddress messageId transactionId } }\",\n        \"variables\": {\n            \"input\": {\n                \"contractId\": \"CONTRACT-OBLIGATION-12345\",\n                \"destinationId\": \"newholder@yieldfabric\",\n                \"idempotencyKey\": str(uuid.uuid4()),\n            }\n        },\n    },\n)\nprint(resp.json()[\"data\"][\"transferObligation\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: TransferObligationInput!) { transferObligation(input: $input) { success obligationId destinationAddress messageId transactionId } }`,\n  {\n    input: {\n      contractId: \"CONTRACT-OBLIGATION-12345\",\n      destinationId: \"newholder@yieldfabric\",\n      idempotencyKey: crypto.randomUUID(),\n    },\n  }\n);\nconsole.log(data.transferObligation);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation TransferObligation($input: TransferObligationInput!) {\n  transferObligation(input: $input) {\n    success\n    obligationId\n    destinationId\n    destinationAddress\n    messageId\n    transactionId\n    contractIds\n    composedContractId\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "createObligation",
                "relation": "prerequisite"
              },
              {
                "operation": "acceptObligation",
                "relation": "prerequisite"
              },
              {
                "operation": "cancelObligation",
                "relation": "alternative"
              },
              {
                "guide": "obligation-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "cancelObligation",
            "kind": "mutation",
            "name": "cancelObligation",
            "service": "yieldfabric-payments",
            "tags": [
              "Obligations"
            ],
            "summary": "Cancel an obligation contract",
            "description": "Cancel an obligation that hasn't been accepted yet (or whose\ncancellation rules permit it post-acceptance). For a DISTRIBUTION the\nsender may only cancel if no recipient has claimed yet.\n\nPass either `contractId` (single obligation) or `contractReference`\n(unified — composed contracts cancel atomically across all sub-legs).\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4) to make retries safe.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. The\ncaller must be the obligation's `obligor` (issuer).\n\n**State transition:** `ACTIVE → CANCELLED`. The obligation NFT is\nburned and any locked funds are released back to the obligor.\n\n**On-chain effect:** queues a `cancel_obligation` message. Response\ncarries `messageId`, `transactionId`, and (for composed contracts) the\nfull list of `contractIds` cancelled.\n",
            "sdl": "mutation CancelObligation($input: CancelObligationInput!) {\n  cancelObligation(input: $input) {\n    success\n    obligationId\n    messageId\n    transactionId\n    contractIds\n    composedContractId\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "description": "Per-class routing is automatic — see `AcceptObligationInput`.\n",
                "type": "object",
                "properties": {
                  "contractId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Legacy field — kept for backward compatibility. If provided, will be\nconverted to ContractReference internally.\n"
                  },
                  "contractReference": {
                    "type": "object",
                    "description": "Unified contract reference — can be either single contract or composed contract.\nExactly one of contractId or composedContractId must be provided.\n",
                    "properties": {
                      "contractId": {
                        "type": "string",
                        "nullable": true,
                        "description": "Single contract ID (mutually exclusive with composedContractId)."
                      },
                      "composedContractId": {
                        "type": "string",
                        "nullable": true,
                        "description": "Composed contract ID (mutually exclusive with contractId)."
                      }
                    }
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "When true, message is routed to manual signature (user signs via UX)\ninstead of automatic execution.\n"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Cancel a single obligation by contract id",
                  "value": {
                    "input": {
                      "contractId": "CONTRACT-OBLIGATION-12345",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440130"
                    }
                  }
                },
                "composed": {
                  "summary": "Cancel a composed-contract bundle (all sub-legs together)",
                  "value": {
                    "input": {
                      "contractReference": {
                        "composedContractId": "COMPOSED-CONTRACT-987654"
                      },
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440131"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "message",
                  "accountAddress",
                  "obligationId",
                  "messageId",
                  "transactionId",
                  "signature",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "obligationId": {
                    "type": "string"
                  },
                  "cancelResult": {
                    "type": "string",
                    "nullable": true
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionId": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "signature": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  },
                  "contractIds": {
                    "type": "array",
                    "nullable": true,
                    "description": "All contract IDs that were cancelled (for composed contracts).",
                    "items": {
                      "type": "string"
                    }
                  },
                  "composedContractId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Composed contract ID if this was a composed contract cancel."
                  },
                  "composedId": {
                    "type": "string",
                    "nullable": true,
                    "description": "Composed operation ID from composed_flow (if used)."
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Unknown contract, contract already accepted (where applicable), or both contract refs omitted."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "FORBIDDEN",
                "status": 403,
                "description": "Caller is not the obligation's `obligor`."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_cancelObligation",
              "resource_uri": "yf://obligations",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/obligations.yaml#/CancelObligationResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: CancelObligationInput!) { cancelObligation(input: $input) { success obligationId messageId transactionId } }\",\"variables\":{\"input\":{\"contractId\":\"CONTRACT-OBLIGATION-12345\",\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440130\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: CancelObligationInput!) { cancelObligation(input: $input) { success obligationId messageId transactionId } }\",\n        \"variables\": {\"input\": {\"contractId\": \"CONTRACT-OBLIGATION-12345\", \"idempotencyKey\": str(uuid.uuid4())}},\n    },\n)\nprint(resp.json()[\"data\"][\"cancelObligation\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: CancelObligationInput!) { cancelObligation(input: $input) { success obligationId messageId transactionId } }`,\n  { input: { contractId: \"CONTRACT-OBLIGATION-12345\", idempotencyKey: crypto.randomUUID() } }\n);\nconsole.log(data.cancelObligation);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation CancelObligation($input: CancelObligationInput!) {\n  cancelObligation(input: $input) {\n    success\n    obligationId\n    messageId\n    transactionId\n    contractIds\n    composedContractId\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "createObligation",
                "relation": "undo"
              },
              {
                "operation": "acceptObligation",
                "relation": "alternative"
              },
              {
                "guide": "obligation-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "expireObligation",
            "kind": "mutation",
            "name": "expireObligation",
            "service": "yieldfabric-payments",
            "tags": [
              "Obligations"
            ],
            "summary": "Expire a pending obligation whose expiry has passed",
            "description": "Marks an unaccepted obligation as expired on chain once its\n`expiryTime` has passed. The underlying `expireObligation(tokenId)`\ncall is **permissionless** and moves no funds — it flips the stored\nexpired flag, which is what opens the vault's payer-reclaim gate for\nescrowed initial payments. Post-expiry, `cancelObligation` reverts\n(\"obligation expired\") and `acceptObligation` reverts (\"obligation\ncannot have expired when accepting\"), so without this call the escrow\nis unreachable.\n\n**Auto-refund:** when the caller is the payer of escrowed initial\npayments, post-processing automatically submits the retrieves under\nthe caller's account, so a payer-initiated expire is a one-call full\nrecovery. Payments escrowed by other senders stay reclaimable by\ntheir own senders (via `accept` on their own payment).\n\n**Idempotency:** if the contract is already `EXPIRED`, the resolver\nreturns a synthesized success without enqueueing a new message\n(`messageId` is empty). Pass `idempotencyKey` (UUIDv4) to make\nsubmission retries safe.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. Any\nauthenticated caller may expire (mirrors the permissionless on-chain\ncall).\n\n**State transition:** `ACTIVE → EXPIRED`. Rejected while the\nobligation is still live (expiry in the future — use\n`cancelObligation` instead), after acceptance (`COMPLETED`), or after\ncancellation (`CANCELLED`).\n\n**On-chain effect:** queues an `expire_obligation` message. Poll the\nmessage-status endpoint and wait for `post_processed_at` before\nreading the contract row or the auto-retrieved payments.\n",
            "sdl": "mutation ExpireObligation($input: ExpireObligationInput!) {\n  expireObligation(input: $input) {\n    success\n    message\n    obligationId\n    contractId\n    messageId\n    transactionId\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "description": "Expire a pending obligation whose expiry has passed. Single contract\nonly — expiry is per-obligation, so composed bundles expire leg by\nleg. Per-class routing is automatic — see `AcceptObligationInput`.\n",
                "type": "object",
                "required": [
                  "contractId"
                ],
                "properties": {
                  "contractId": {
                    "type": "string"
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "When true, message is routed to manual signature (user signs via UX)\ninstead of automatic execution.\n"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Expire a lapsed obligation by contract id",
                  "value": {
                    "input": {
                      "contractId": "CONTRACT-OBLIGATION-12345",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440140"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "message",
                  "accountAddress",
                  "obligationId",
                  "contractId",
                  "messageId",
                  "transactionId",
                  "signature",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "obligationId": {
                    "type": "string"
                  },
                  "contractId": {
                    "type": "string"
                  },
                  "messageId": {
                    "type": "string",
                    "description": "Empty when the resolver short-circuited (contract already EXPIRED) —\nno new MQ message was enqueued.\n"
                  },
                  "transactionId": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "signature": {
                    "type": "string"
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Unknown contract; obligation not yet past its expiry (use\n`cancelObligation`); already accepted (`COMPLETED`); already\n`CANCELLED`; or a cancel/expire is already in flight for the\ncontract.\n"
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_expireObligation",
              "resource_uri": "yf://obligations",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/obligations.yaml#/ExpireObligationResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: ExpireObligationInput!) { expireObligation(input: $input) { success obligationId messageId transactionId } }\",\"variables\":{\"input\":{\"contractId\":\"CONTRACT-OBLIGATION-12345\",\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440140\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: ExpireObligationInput!) { expireObligation(input: $input) { success obligationId messageId transactionId } }\",\n        \"variables\": {\"input\": {\"contractId\": \"CONTRACT-OBLIGATION-12345\", \"idempotencyKey\": str(uuid.uuid4())}},\n    },\n)\nprint(resp.json()[\"data\"][\"expireObligation\"])\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation ExpireObligation($input: ExpireObligationInput!) {\n  expireObligation(input: $input) {\n    success\n    message\n    obligationId\n    contractId\n    messageId\n    transactionId\n    timestamp\n  }\n}\n"
              }
            ]
          },
          {
            "operationId": "createSwap",
            "kind": "mutation",
            "name": "createSwap",
            "service": "yieldfabric-payments",
            "tags": [
              "Swaps"
            ],
            "summary": "Create an atomic or repo swap with a counterparty",
            "description": "Create a swap agreement between the caller (initiator) and a\n`counterparty`. Required inputs are `swapId` (caller-generated unique\nid), `counterparty` (entity name), and `deadline` (unix timestamp after\nwhich the swap can no longer be completed).\n\n**Atomic swap** vs **repo swap** is determined by `expiry`: omit (or set\n`expiry = 0`) for atomic immediate settlement; set `expiry > deadline`\nto make it a repo swap with collateral that can be repurchased before\nthe `expiry`. Use the `*Collateral*` and `*Repurchase*` fields to attach\ncollateral and repurchase legs.\n\nUse the `*ContractReferences` fields for the unified contract input\nshape (supports composed contracts); the `*ObligationIds` fields are\nlegacy aliases kept for backward compatibility.\n\n**Ownership.** The initiator can only offer obligations or collateral\nits swap wallet is the HOLDER of. An **explicitly-named** reference (a\n`*ContractReferences` entry with a `contractId`, or a legacy\n`*ObligationIds` entry) the wallet does not hold is **rejected up\nfront** with `\"Initiator does not hold obligation contract <id> …\"`\n(or `\"… collateral contract <id> …\"`) — the swap is never silently\nunder-collateralized. A `composedContractId` reference instead expands\nto a whole position; its un-held *nested* legs (e.g. an escrowed\nunderlying) are dropped silently, pledging only the held leg. If you\nhold the asset in a different wallet, pass that `walletId`.\n\n**Claim-gated obligations.** Offered obligations may live in a\nclaim-gated (ERC-3643/Tokeny) `ConfidentialObligation` class. The\nper-class contract is **auto-resolved** from the offered obligations —\nno extra input — and recorded on-chain, so `completeSwap` / `cancelSwap`\n/ `repurchaseSwap` / roll / `expireCollateral` all route to the same\nclass. Escrow into the swap is exempt (the swap is pass-through infra),\nbut the outbound hop on `completeSwap` still gates: an **unverified**\nrecipient's complete reverts on-chain with `Recipient not verified`\n(surfaced via message-status polling). A soul-bound\n(`transferable:false`) class cannot be escrowed at all (`createSwap`'s\non-chain step reverts `Class not transferable`). See the\n[swap-lifecycle guide](../../guides/swap-lifecycle.md).\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4) to make retries safe.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. When\n`walletId` is set, the initiator signs as that sub-account.\n\n**On-chain effect:** queues a `create_swap` message. On confirmation the\ninitiator's obligations and collateral are locked, the initiator's\nexpected payments are created, and the response carries `swapId`,\n`messageId`, `transactionId`. The swap starts in `PENDING`; the\ncounterparty completes it with `completeSwap`.\n",
            "sdl": "mutation CreateSwap($input: CreateSwapInput!) {\n  createSwap(input: $input) {\n    success\n    swapId\n    messageId\n    transactionId\n    swapResult\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "description": "Unified swap input type — handles all swap scenarios.\n\nThis single input type supports all swap configurations:\n- **Obligation swaps**: Provide `initiatorObligationIds` + `initiatorExpectedPayments`\n- **Payment swaps**: Provide `initiatorExpectedPayments` + `counterpartyExpectedPayments`\n- **Mixed swaps**: Any combination of obligations and expected payments\n- **Repo swaps with collateral**: Provide collateral and repurchase requirements\n\nEmpty/None values are allowed for any field, enabling maximum flexibility.\n\n**Ownership.** The initiator can only offer obligations/collateral its\nswap wallet is the HOLDER of. An explicitly-named reference (a\n`*ContractReferences` entry with `contractId`, or a legacy `*ObligationIds`\nentry) it does not hold is rejected up front (`\"Initiator does not hold …\ncontract <id>\"`); a `composedContractId` reference silently drops its\nun-held nested legs (e.g. an escrowed underlying), pledging only the held\nleg. Pass `walletId` when the asset lives on a non-default wallet.\n",
                "required": [
                  "swapId",
                  "counterparty",
                  "deadline"
                ],
                "properties": {
                  "swapId": {
                    "type": "string"
                  },
                  "counterparty": {
                    "type": "string",
                    "description": "Entity name of the counterparty."
                  },
                  "counterpartyWalletId": {
                    "type": "string",
                    "nullable": true
                  },
                  "deadline": {
                    "type": "string",
                    "description": "Unix timestamp (string) or ISO-8601 deadline before which the swap must complete."
                  },
                  "initiatorObligationIds": {
                    "type": "array",
                    "nullable": true,
                    "description": "Legacy field — kept for backward compatibility.",
                    "items": {
                      "type": "string"
                    }
                  },
                  "initiatorContractReferences": {
                    "type": "array",
                    "nullable": true,
                    "description": "Unified contract references for initiator obligations (can be single or composed contracts).",
                    "items": {
                      "type": "object",
                      "description": "Unified contract reference — can be either single contract or composed contract.\nExactly one of contractId or composedContractId must be provided.\n",
                      "properties": {
                        "contractId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Single contract ID (mutually exclusive with composedContractId)."
                        },
                        "composedContractId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Composed contract ID (mutually exclusive with contractId)."
                        }
                      }
                    }
                  },
                  "initiatorExpectedPayments": {
                    "type": "object",
                    "required": [
                      "amount",
                      "payments"
                    ],
                    "properties": {
                      "amount": {
                        "type": "string",
                        "pattern": "^[0-9]+$",
                        "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                      },
                      "denomination": {
                        "type": "string",
                        "nullable": true
                      },
                      "obligor": {
                        "type": "string",
                        "nullable": true
                      },
                      "payments": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "description": "Shared input type for vault payment data. Used by both contract and swap\nflows to avoid duplication.\n",
                          "properties": {
                            "oracleAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleOwner": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeySender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSenderSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeyRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipientSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockReceiver": {
                              "type": "string",
                              "nullable": true
                            },
                            "linearVesting": {
                              "type": "boolean",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  },
                  "counterpartyObligationIds": {
                    "type": "array",
                    "nullable": true,
                    "description": "Legacy field — kept for backward compatibility.",
                    "items": {
                      "type": "string"
                    }
                  },
                  "counterpartyContractReferences": {
                    "type": "array",
                    "nullable": true,
                    "description": "Unified contract references for counterparty obligations (can be single or composed contracts).",
                    "items": {
                      "type": "object",
                      "description": "Unified contract reference — can be either single contract or composed contract.\nExactly one of contractId or composedContractId must be provided.\n",
                      "properties": {
                        "contractId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Single contract ID (mutually exclusive with composedContractId)."
                        },
                        "composedContractId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Composed contract ID (mutually exclusive with contractId)."
                        }
                      }
                    }
                  },
                  "counterpartyExpectedPayments": {
                    "type": "object",
                    "required": [
                      "amount",
                      "payments"
                    ],
                    "properties": {
                      "amount": {
                        "type": "string",
                        "pattern": "^[0-9]+$",
                        "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                      },
                      "denomination": {
                        "type": "string",
                        "nullable": true
                      },
                      "obligor": {
                        "type": "string",
                        "nullable": true
                      },
                      "payments": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "description": "Shared input type for vault payment data. Used by both contract and swap\nflows to avoid duplication.\n",
                          "properties": {
                            "oracleAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleOwner": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeySender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSenderSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeyRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipientSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockReceiver": {
                              "type": "string",
                              "nullable": true
                            },
                            "linearVesting": {
                              "type": "boolean",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  },
                  "initiatorCollateralObligationIds": {
                    "type": "array",
                    "nullable": true,
                    "description": "Legacy field — kept for backward compatibility.",
                    "items": {
                      "type": "string"
                    }
                  },
                  "initiatorCollateralContractReferences": {
                    "type": "array",
                    "nullable": true,
                    "description": "Unified contract references for initiator collateral obligations.",
                    "items": {
                      "type": "object",
                      "description": "Unified contract reference — can be either single contract or composed contract.\nExactly one of contractId or composedContractId must be provided.\n",
                      "properties": {
                        "contractId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Single contract ID (mutually exclusive with composedContractId)."
                        },
                        "composedContractId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Composed contract ID (mutually exclusive with contractId)."
                        }
                      }
                    }
                  },
                  "initiatorCollateralPayments": {
                    "type": "object",
                    "required": [
                      "amount",
                      "payments"
                    ],
                    "properties": {
                      "amount": {
                        "type": "string",
                        "pattern": "^[0-9]+$",
                        "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                      },
                      "denomination": {
                        "type": "string",
                        "nullable": true
                      },
                      "obligor": {
                        "type": "string",
                        "nullable": true
                      },
                      "payments": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "description": "Shared input type for vault payment data. Used by both contract and swap\nflows to avoid duplication.\n",
                          "properties": {
                            "oracleAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleOwner": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeySender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSenderSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeyRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipientSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockReceiver": {
                              "type": "string",
                              "nullable": true
                            },
                            "linearVesting": {
                              "type": "boolean",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  },
                  "counterpartyCollateralObligationIds": {
                    "type": "array",
                    "nullable": true,
                    "description": "Legacy field — kept for backward compatibility.",
                    "items": {
                      "type": "string"
                    }
                  },
                  "counterpartyCollateralContractReferences": {
                    "type": "array",
                    "nullable": true,
                    "description": "Unified contract references for counterparty collateral obligations.",
                    "items": {
                      "type": "object",
                      "description": "Unified contract reference — can be either single contract or composed contract.\nExactly one of contractId or composedContractId must be provided.\n",
                      "properties": {
                        "contractId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Single contract ID (mutually exclusive with composedContractId)."
                        },
                        "composedContractId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Composed contract ID (mutually exclusive with contractId)."
                        }
                      }
                    }
                  },
                  "counterpartyCollateralPayments": {
                    "type": "object",
                    "required": [
                      "amount",
                      "payments"
                    ],
                    "properties": {
                      "amount": {
                        "type": "string",
                        "pattern": "^[0-9]+$",
                        "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                      },
                      "denomination": {
                        "type": "string",
                        "nullable": true
                      },
                      "obligor": {
                        "type": "string",
                        "nullable": true
                      },
                      "payments": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "description": "Shared input type for vault payment data. Used by both contract and swap\nflows to avoid duplication.\n",
                          "properties": {
                            "oracleAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleOwner": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeySender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSenderSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeyRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipientSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockReceiver": {
                              "type": "string",
                              "nullable": true
                            },
                            "linearVesting": {
                              "type": "boolean",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  },
                  "initiatorRepurchaseObligationIds": {
                    "type": "array",
                    "nullable": true,
                    "description": "Legacy field — kept for backward compatibility.",
                    "items": {
                      "type": "string"
                    }
                  },
                  "initiatorRepurchaseContractReferences": {
                    "type": "array",
                    "nullable": true,
                    "description": "Unified contract references for initiator repurchase obligations.",
                    "items": {
                      "type": "object",
                      "description": "Unified contract reference — can be either single contract or composed contract.\nExactly one of contractId or composedContractId must be provided.\n",
                      "properties": {
                        "contractId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Single contract ID (mutually exclusive with composedContractId)."
                        },
                        "composedContractId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Composed contract ID (mutually exclusive with contractId)."
                        }
                      }
                    }
                  },
                  "initiatorRepurchasePayments": {
                    "type": "object",
                    "required": [
                      "amount",
                      "payments"
                    ],
                    "properties": {
                      "amount": {
                        "type": "string",
                        "pattern": "^[0-9]+$",
                        "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                      },
                      "denomination": {
                        "type": "string",
                        "nullable": true
                      },
                      "obligor": {
                        "type": "string",
                        "nullable": true
                      },
                      "payments": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "description": "Shared input type for vault payment data. Used by both contract and swap\nflows to avoid duplication.\n",
                          "properties": {
                            "oracleAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleOwner": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeySender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSenderSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeyRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipientSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockReceiver": {
                              "type": "string",
                              "nullable": true
                            },
                            "linearVesting": {
                              "type": "boolean",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  },
                  "counterpartyRepurchaseObligationIds": {
                    "type": "array",
                    "nullable": true,
                    "description": "Legacy field — kept for backward compatibility.",
                    "items": {
                      "type": "string"
                    }
                  },
                  "counterpartyRepurchaseContractReferences": {
                    "type": "array",
                    "nullable": true,
                    "description": "Unified contract references for counterparty repurchase obligations.",
                    "items": {
                      "type": "object",
                      "description": "Unified contract reference — can be either single contract or composed contract.\nExactly one of contractId or composedContractId must be provided.\n",
                      "properties": {
                        "contractId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Single contract ID (mutually exclusive with composedContractId)."
                        },
                        "composedContractId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Composed contract ID (mutually exclusive with contractId)."
                        }
                      }
                    }
                  },
                  "counterpartyRepurchasePayments": {
                    "type": "object",
                    "required": [
                      "amount",
                      "payments"
                    ],
                    "properties": {
                      "amount": {
                        "type": "string",
                        "pattern": "^[0-9]+$",
                        "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                      },
                      "denomination": {
                        "type": "string",
                        "nullable": true
                      },
                      "obligor": {
                        "type": "string",
                        "nullable": true
                      },
                      "payments": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "description": "Shared input type for vault payment data. Used by both contract and swap\nflows to avoid duplication.\n",
                          "properties": {
                            "oracleAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleOwner": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeySender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSenderSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeyRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipientSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockReceiver": {
                              "type": "string",
                              "nullable": true
                            },
                            "linearVesting": {
                              "type": "boolean",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  },
                  "expiry": {
                    "type": "string",
                    "nullable": true,
                    "description": "Repurchase expiry for repo swaps. Unix timestamp / ISO-8601."
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  },
                  "walletId": {
                    "type": "string",
                    "nullable": true
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "When true, message is routed to manual signature (user signs via UX)\ninstead of automatic execution.\n"
                  },
                  "name": {
                    "type": "string",
                    "nullable": true,
                    "description": "Optional display name for the swap/repo (e.g. \"Q4 2027 Repo\"). When set,\nused as the composed contract name instead of auto-generated\n\"Repo Swap - Swap {id}\".\n"
                  },
                  "auctionBid": {
                    "type": "object",
                    "required": [
                      "auctionId",
                      "amount"
                    ],
                    "properties": {
                      "auctionId": {
                        "type": "string"
                      },
                      "amount": {
                        "type": "string",
                        "pattern": "^[0-9]+$",
                        "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                      },
                      "priceOrRate": {
                        "type": "string",
                        "nullable": true
                      },
                      "walletId": {
                        "type": "string",
                        "nullable": true
                      }
                    }
                  }
                }
              },
              "examples": {
                "atomic-swap": {
                  "summary": "Atomic swap — initiator's obligation for counterparty's USD payment, settles immediately",
                  "value": {
                    "input": {
                      "swapId": "SWAP-2026-q1-001",
                      "counterparty": "bob@yieldfabric",
                      "deadline": "1735603200",
                      "initiatorContractReferences": [
                        {
                          "contractId": "CONTRACT-OBLIGATION-12345"
                        }
                      ],
                      "counterpartyExpectedPayments": {
                        "amount": "1000",
                        "denomination": "USD",
                        "payments": [
                          {
                            "linearVesting": false
                          }
                        ]
                      },
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440200"
                    }
                  }
                },
                "repo-swap-30day": {
                  "summary": "30-day USD 1000 repo with bond collateral and a 5% repurchase premium",
                  "value": {
                    "input": {
                      "swapId": "SWAP-repo-2026-q1-001",
                      "counterparty": "lender@yieldfabric",
                      "deadline": "1735603200",
                      "expiry": "1738195200",
                      "name": "Q4 2027 Repo",
                      "initiatorCollateralContractReferences": [
                        {
                          "contractId": "CONTRACT-BOND-AAA-7788"
                        }
                      ],
                      "counterpartyExpectedPayments": {
                        "amount": "1000",
                        "denomination": "USD",
                        "payments": [
                          {
                            "linearVesting": false
                          }
                        ]
                      },
                      "initiatorRepurchasePayments": {
                        "amount": "1050",
                        "denomination": "USD",
                        "payments": [
                          {
                            "linearVesting": false
                          }
                        ]
                      },
                      "walletId": "WALLET-treasury-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440201"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "description": "Unified swap creation response.",
                "required": [
                  "success",
                  "message",
                  "accountAddress",
                  "swapId",
                  "counterparty",
                  "messageId",
                  "transactionId",
                  "signature",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "swapId": {
                    "type": "string"
                  },
                  "counterparty": {
                    "type": "string"
                  },
                  "swapResult": {
                    "type": "string",
                    "nullable": true
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionId": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "signature": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Deadline in the past, `expiry <= deadline` for repo swaps, missing collateral when expiry set, or an explicitly-named obligation/collateral the initiator's wallet is not the HOLDER of (`\"Initiator does not hold … contract <id>\"`), etc."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "CONFLICT",
                "status": 409,
                "description": "`swapId` is already in use or `idempotencyKey` was reused with a different payload."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_createSwap",
              "resource_uri": "yf://swaps",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/swaps.yaml#/CreateSwapResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: CreateSwapInput!) { createSwap(input: $input) { success swapId messageId transactionId } }\",\"variables\":{\"input\":{\"swapId\":\"SWAP-2026-q1-001\",\"counterparty\":\"bob@yieldfabric\",\"deadline\":\"1735603200\",\"initiatorContractReferences\":[{\"contractId\":\"CONTRACT-OBLIGATION-12345\"}],\"counterpartyExpectedPayments\":{\"amount\":\"1000\",\"denomination\":\"USD\",\"payments\":[{\"linearVesting\":false}]},\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440200\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: CreateSwapInput!) { createSwap(input: $input) { success swapId messageId transactionId } }\",\n        \"variables\": {\n            \"input\": {\n                \"swapId\": \"SWAP-2026-q1-001\",\n                \"counterparty\": \"bob@yieldfabric\",\n                \"deadline\": \"1735603200\",\n                \"initiatorContractReferences\": [{\"contractId\": \"CONTRACT-OBLIGATION-12345\"}],\n                \"counterpartyExpectedPayments\": {\n                    \"amount\": \"1000\",\n                    \"denomination\": \"USD\",\n                    \"payments\": [{\"linearVesting\": False}],\n                },\n                \"idempotencyKey\": str(uuid.uuid4()),\n            }\n        },\n    },\n)\nprint(resp.json()[\"data\"][\"createSwap\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: CreateSwapInput!) { createSwap(input: $input) { success swapId messageId transactionId } }`,\n  {\n    input: {\n      swapId: \"SWAP-2026-q1-001\",\n      counterparty: \"bob@yieldfabric\",\n      deadline: \"1735603200\",\n      initiatorContractReferences: [{ contractId: \"CONTRACT-OBLIGATION-12345\" }],\n      counterpartyExpectedPayments: {\n        amount: \"1000\",\n        denomination: \"USD\",\n        payments: [{ linearVesting: false }],\n      },\n      idempotencyKey: crypto.randomUUID(),\n    },\n  }\n);\nconsole.log(data.createSwap);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation CreateSwap($input: CreateSwapInput!) {\n  createSwap(input: $input) {\n    success\n    swapId\n    messageId\n    transactionId\n    swapResult\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "completeSwap",
                "relation": "next"
              },
              {
                "operation": "cancelSwap",
                "relation": "undo"
              },
              {
                "operation": "repurchaseSwap",
                "relation": "next"
              },
              {
                "operation": "initiateRoll",
                "relation": "next"
              },
              {
                "guide": "swap-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "completeSwap",
            "kind": "mutation",
            "name": "completeSwap",
            "service": "yieldfabric-payments",
            "tags": [
              "Swaps"
            ],
            "summary": "Counterparty completes a pending swap by posting their leg",
            "description": "Counterparty completes a swap previously created by the initiator,\natomically posting their obligations / payments / collateral. The only\nrequired input is `swapId`.\n\nFor repo swaps, the counterparty's collateral (if any) goes in either\n`counterpartyCollateralObligationIds` (legacy) or implicitly via the\nswap definition. `counterpartyCollateralPayments` carries any\ncollateral-side payments.\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4) to make retries safe.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. The\ncaller must be the swap's `counterparty`. When `walletId` /\n`counterpartyWalletId` are set, the counterparty signs as that\nsub-account.\n\n**Group counterparty:** the `counterparty` may be a group / shared account,\nwhich funds its expected payments from its own balance. The caller presents a\n**group-delegation JWT** so the bearer acts AS the group — there is no\n`acting_as_group` field on this mutation. In a DMS deal, the `acting_as_group`\ninput on the `complete_swap` step is consumed by the bridge, which mints that\ndelegation JWT before calling `completeSwap` (the loan-origination disbursement\npattern). See the [swap-lifecycle guide](../../guides/swap-lifecycle.md).\n\n**State transition:** `PENDING → ACTIVE` (repo) or `PENDING → COMPLETED`\n(atomic). Settlement is atomic — either both sides exchange or\nneither does.\n\n**On-chain effect:** queues a `complete_swap` message. Response carries\n`swapId`, `messageId`, and `transactionId`.\n",
            "sdl": "mutation CompleteSwap($input: CompleteSwapInput!) {\n  completeSwap(input: $input) {\n    success\n    swapId\n    messageId\n    transactionId\n    completeResult\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "swapId"
                ],
                "properties": {
                  "swapId": {
                    "type": "string"
                  },
                  "counterpartyCollateralObligationIds": {
                    "type": "array",
                    "nullable": true,
                    "items": {
                      "type": "string"
                    }
                  },
                  "counterpartyCollateralPayments": {
                    "type": "object",
                    "required": [
                      "amount",
                      "payments"
                    ],
                    "properties": {
                      "amount": {
                        "type": "string",
                        "pattern": "^[0-9]+$",
                        "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                      },
                      "denomination": {
                        "type": "string",
                        "nullable": true
                      },
                      "obligor": {
                        "type": "string",
                        "nullable": true
                      },
                      "payments": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "description": "Shared input type for vault payment data. Used by both contract and swap\nflows to avoid duplication.\n",
                          "properties": {
                            "oracleAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleOwner": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeySender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSenderSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeyRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipientSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockReceiver": {
                              "type": "string",
                              "nullable": true
                            },
                            "linearVesting": {
                              "type": "boolean",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  },
                  "walletId": {
                    "type": "string",
                    "nullable": true
                  },
                  "counterpartyWalletId": {
                    "type": "string",
                    "nullable": true
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "When true, message is routed to manual signature (user signs via UX)\ninstead of automatic execution.\n"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Counterparty completes a swap by posting nothing extra (atomic, all defined at create time)",
                  "value": {
                    "input": {
                      "swapId": "SWAP-2026-q1-001",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440210"
                    }
                  }
                },
                "with-counterparty-collateral": {
                  "summary": "Counterparty also posts collateral at completion time",
                  "value": {
                    "input": {
                      "swapId": "SWAP-repo-2026-q1-001",
                      "counterpartyCollateralObligationIds": [
                        "CONTRACT-OBLIGATION-collateral-9911"
                      ],
                      "walletId": "WALLET-counterparty-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440211"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "message",
                  "accountAddress",
                  "swapId",
                  "messageId",
                  "transactionId",
                  "signature",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "swapId": {
                    "type": "string"
                  },
                  "completeResult": {
                    "type": "string",
                    "nullable": true
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionId": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "signature": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Unknown swap, past deadline, or missing counterparty leg."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "FORBIDDEN",
                "status": 403,
                "description": "Caller is not the swap's `counterparty`."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_completeSwap",
              "resource_uri": "yf://swaps",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/swaps.yaml#/CompleteSwapResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: CompleteSwapInput!) { completeSwap(input: $input) { success swapId messageId transactionId } }\",\"variables\":{\"input\":{\"swapId\":\"SWAP-2026-q1-001\",\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440210\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: CompleteSwapInput!) { completeSwap(input: $input) { success swapId messageId transactionId } }\",\n        \"variables\": {\"input\": {\"swapId\": \"SWAP-2026-q1-001\", \"idempotencyKey\": str(uuid.uuid4())}},\n    },\n)\nprint(resp.json()[\"data\"][\"completeSwap\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: CompleteSwapInput!) { completeSwap(input: $input) { success swapId messageId transactionId } }`,\n  { input: { swapId: \"SWAP-2026-q1-001\", idempotencyKey: crypto.randomUUID() } }\n);\nconsole.log(data.completeSwap);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation CompleteSwap($input: CompleteSwapInput!) {\n  completeSwap(input: $input) {\n    success\n    swapId\n    messageId\n    transactionId\n    completeResult\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "createSwap",
                "relation": "prerequisite"
              },
              {
                "operation": "repurchaseSwap",
                "relation": "next"
              },
              {
                "operation": "expireCollateral",
                "relation": "next"
              },
              {
                "guide": "swap-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "cancelSwap",
            "kind": "mutation",
            "name": "cancelSwap",
            "service": "yieldfabric-payments",
            "tags": [
              "Swaps"
            ],
            "summary": "Cancel a pending swap before completion",
            "description": "Cancel a swap that's still `PENDING` (not yet completed by the\ncounterparty). Required inputs are `swapId`, `key`, and `value` — the\n`key`/`value` pair records a structured reason on chain for audit\n(e.g. `key: \"reason\"`, `value: \"deadline_missed\"`).\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4) to make retries safe.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. The\ncaller must be the swap's `initiator`. When `walletId` is set, the\ncaller signs as that sub-account.\n\n**State transition:** `PENDING → CANCELLED`. The initiator's locked\nobligations and collateral are released back.\n\n**On-chain effect:** queues a `cancel_swap` message. Response carries\n`swapId`, `messageId`, and `transactionId`.\n",
            "sdl": "mutation CancelSwap($input: CancelSwapInput!) {\n  cancelSwap(input: $input) {\n    success\n    swapId\n    messageId\n    transactionId\n    cancelResult\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "swapId",
                  "key",
                  "value"
                ],
                "properties": {
                  "swapId": {
                    "type": "string"
                  },
                  "key": {
                    "type": "string",
                    "description": "Reason key (audit metadata)."
                  },
                  "value": {
                    "type": "string",
                    "description": "Reason value (audit metadata)."
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  },
                  "walletId": {
                    "type": "string",
                    "nullable": true
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "When true, message is routed to manual signature (user signs via UX)\ninstead of automatic execution.\n"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Cancel a pending swap with an audit reason",
                  "value": {
                    "input": {
                      "swapId": "SWAP-2026-q1-001",
                      "key": "reason",
                      "value": "deadline_missed",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440220"
                    }
                  }
                },
                "with-wallet": {
                  "summary": "Cancel scoped to a sub-account",
                  "value": {
                    "input": {
                      "swapId": "SWAP-2026-q1-002",
                      "key": "reason",
                      "value": "counterparty_unresponsive",
                      "walletId": "WALLET-treasury-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440221"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "message",
                  "accountAddress",
                  "swapId",
                  "messageId",
                  "transactionId",
                  "signature",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "swapId": {
                    "type": "string"
                  },
                  "cancelResult": {
                    "type": "string",
                    "nullable": true
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionId": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "signature": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Unknown swap, swap no longer cancellable (already ACTIVE/COMPLETED)."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "FORBIDDEN",
                "status": 403,
                "description": "Caller is not the swap's initiator."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_cancelSwap",
              "resource_uri": "yf://swaps",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/swaps.yaml#/CancelSwapResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: CancelSwapInput!) { cancelSwap(input: $input) { success swapId messageId transactionId } }\",\"variables\":{\"input\":{\"swapId\":\"SWAP-2026-q1-001\",\"key\":\"reason\",\"value\":\"deadline_missed\",\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440220\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: CancelSwapInput!) { cancelSwap(input: $input) { success swapId messageId transactionId } }\",\n        \"variables\": {\n            \"input\": {\n                \"swapId\": \"SWAP-2026-q1-001\",\n                \"key\": \"reason\",\n                \"value\": \"deadline_missed\",\n                \"idempotencyKey\": str(uuid.uuid4()),\n            }\n        },\n    },\n)\nprint(resp.json()[\"data\"][\"cancelSwap\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: CancelSwapInput!) { cancelSwap(input: $input) { success swapId messageId transactionId } }`,\n  {\n    input: {\n      swapId: \"SWAP-2026-q1-001\",\n      key: \"reason\",\n      value: \"deadline_missed\",\n      idempotencyKey: crypto.randomUUID(),\n    },\n  }\n);\nconsole.log(data.cancelSwap);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation CancelSwap($input: CancelSwapInput!) {\n  cancelSwap(input: $input) {\n    success\n    swapId\n    messageId\n    transactionId\n    cancelResult\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "createSwap",
                "relation": "undo"
              },
              {
                "operation": "completeSwap",
                "relation": "alternative"
              },
              {
                "guide": "swap-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "repurchaseSwap",
            "kind": "mutation",
            "name": "repurchaseSwap",
            "service": "yieldfabric-payments",
            "tags": [
              "Swaps"
            ],
            "summary": "Initiator repurchases collateral on an active repo swap",
            "description": "Initiator pays the repurchase price (defined at `createSwap` time) to\nreclaim their collateral on an `ACTIVE` repo swap before its `expiry`.\nRequired input is `swapId`.\n\nPass `repurchaseContractReferences` and/or `repurchasePaymentIds` to\nsatisfy the repurchase leg with specific obligations / payments. Omit\nthese to use the legs registered at create time.\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4) to make retries safe.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. The\ncaller must be the swap's `initiator`.\n\n**State transition:** `ACTIVE → REPURCHASED`. Collateral is returned to\nthe initiator; repurchase payments flow to the counterparty.\n\n**On-chain effect:** queues a `repurchase_swap` message. Response\ncarries `swapId`, `messageId`, and `transactionId`.\n",
            "sdl": "mutation RepurchaseSwap($input: RepurchaseSwapInput!) {\n  repurchaseSwap(input: $input) {\n    success\n    swapId\n    messageId\n    transactionId\n    repurchaseResult\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "description": "Repurchase swap collateral input.",
                "required": [
                  "swapId"
                ],
                "properties": {
                  "swapId": {
                    "type": "string"
                  },
                  "repurchaseObligationIds": {
                    "type": "array",
                    "nullable": true,
                    "description": "Legacy field — kept for backward compatibility.",
                    "items": {
                      "type": "string"
                    }
                  },
                  "repurchaseContractReferences": {
                    "type": "array",
                    "nullable": true,
                    "description": "Unified contract references for repurchase obligations (can be single or composed contracts).",
                    "items": {
                      "type": "object",
                      "description": "Unified contract reference — can be either single contract or composed contract.\nExactly one of contractId or composedContractId must be provided.\n",
                      "properties": {
                        "contractId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Single contract ID (mutually exclusive with composedContractId)."
                        },
                        "composedContractId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Composed contract ID (mutually exclusive with contractId)."
                        }
                      }
                    }
                  },
                  "repurchasePaymentIds": {
                    "type": "array",
                    "nullable": true,
                    "items": {
                      "type": "string"
                    }
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "When true, message is routed to manual signature (user signs via UX)\ninstead of automatic execution.\n"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Repurchase using the legs registered at create time",
                  "value": {
                    "input": {
                      "swapId": "SWAP-repo-2026-q1-001",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440230"
                    }
                  }
                },
                "with-explicit-payments": {
                  "summary": "Repurchase satisfying the leg with explicit payment ids",
                  "value": {
                    "input": {
                      "swapId": "SWAP-repo-2026-q1-002",
                      "repurchasePaymentIds": [
                        "PAYMENT-repurchase-7c4a1d8e-3b9d-4c10-9f8e-1a2b3c4d5e6f"
                      ],
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440231"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "message",
                  "accountAddress",
                  "swapId",
                  "messageId",
                  "transactionId",
                  "signature",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "swapId": {
                    "type": "string"
                  },
                  "repurchaseResult": {
                    "type": "string",
                    "nullable": true
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionId": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "signature": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Unknown swap, swap not in `ACTIVE` state, past `expiry`, or insufficient repurchase payments."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "FORBIDDEN",
                "status": 403,
                "description": "Caller is not the swap's `initiator`."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_repurchaseSwap",
              "resource_uri": "yf://swaps",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/swaps.yaml#/RepurchaseSwapResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: RepurchaseSwapInput!) { repurchaseSwap(input: $input) { success swapId messageId transactionId } }\",\"variables\":{\"input\":{\"swapId\":\"SWAP-repo-2026-q1-001\",\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440230\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: RepurchaseSwapInput!) { repurchaseSwap(input: $input) { success swapId messageId transactionId } }\",\n        \"variables\": {\"input\": {\"swapId\": \"SWAP-repo-2026-q1-001\", \"idempotencyKey\": str(uuid.uuid4())}},\n    },\n)\nprint(resp.json()[\"data\"][\"repurchaseSwap\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: RepurchaseSwapInput!) { repurchaseSwap(input: $input) { success swapId messageId transactionId } }`,\n  { input: { swapId: \"SWAP-repo-2026-q1-001\", idempotencyKey: crypto.randomUUID() } }\n);\nconsole.log(data.repurchaseSwap);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation RepurchaseSwap($input: RepurchaseSwapInput!) {\n  repurchaseSwap(input: $input) {\n    success\n    swapId\n    messageId\n    transactionId\n    repurchaseResult\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "completeSwap",
                "relation": "prerequisite"
              },
              {
                "operation": "expireCollateral",
                "relation": "alternative"
              },
              {
                "operation": "initiateRoll",
                "relation": "alternative"
              },
              {
                "guide": "swap-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "initiateRoll",
            "kind": "mutation",
            "name": "initiateRoll",
            "service": "yieldfabric-payments",
            "tags": [
              "Swaps"
            ],
            "summary": "Open a new repo to roll an existing one into",
            "description": "First step of a **repo roll**: open a fresh repo (with a new\ncounterparty and new terms) into which the collateral of a completed\nold repo will migrate. The new repo starts in `PENDING`; `completeRoll`\nis what actually settles the old repo's repurchase and moves collateral.\n\nRequired inputs are `oldSwapId`, `newSwapId` (caller-generated unique\nid for the new repo), `newCounterparty`, and `newDeadline`. Set\n`newExpiry` to make the new leg a repo (typical) — if omitted, the new\nleg is atomic.\n\nUse `newInitiatorRepurchasePayments` / `newCounterpartyRepurchasePayments`\nto define the new repo's repurchase obligations. The optional\n`newInitiatorExpectedPayments` lets you collect an upfront payment from\nthe new counterparty on top of (or instead of) the derived old-repo\nrepurchase amount.\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4) to make retries safe.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. Caller\nmust be the initiator of `oldSwapId`.\n\n**On-chain effect:** queues an `initiate_roll` message; on confirmation\na new PENDING repo exists and the response carries `oldSwapId`,\n`newSwapId`, `messageId`, and `transactionId`. The new counterparty\nmust call `completeRoll` to finish the migration.\n",
            "sdl": "mutation InitiateRoll($input: RollRepoInput!) {\n  initiateRoll(input: $input) {\n    success\n    oldSwapId\n    newSwapId\n    messageId\n    transactionId\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "oldSwapId",
                  "newSwapId",
                  "newCounterparty",
                  "newDeadline"
                ],
                "properties": {
                  "oldSwapId": {
                    "type": "string"
                  },
                  "newSwapId": {
                    "type": "string"
                  },
                  "newCounterparty": {
                    "type": "string"
                  },
                  "newCounterpartyWalletId": {
                    "type": "string",
                    "nullable": true
                  },
                  "newDeadline": {
                    "type": "string"
                  },
                  "newExpiry": {
                    "type": "string",
                    "nullable": true
                  },
                  "newCounterpartyExpectedPayments": {
                    "type": "object",
                    "required": [
                      "amount",
                      "payments"
                    ],
                    "properties": {
                      "amount": {
                        "type": "string",
                        "pattern": "^[0-9]+$",
                        "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                      },
                      "denomination": {
                        "type": "string",
                        "nullable": true
                      },
                      "obligor": {
                        "type": "string",
                        "nullable": true
                      },
                      "payments": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "description": "Shared input type for vault payment data. Used by both contract and swap\nflows to avoid duplication.\n",
                          "properties": {
                            "oracleAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleOwner": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeySender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSenderSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeyRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipientSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockReceiver": {
                              "type": "string",
                              "nullable": true
                            },
                            "linearVesting": {
                              "type": "boolean",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  },
                  "newInitiatorExpectedPayments": {
                    "type": "object",
                    "required": [
                      "amount",
                      "payments"
                    ],
                    "properties": {
                      "amount": {
                        "type": "string",
                        "pattern": "^[0-9]+$",
                        "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                      },
                      "denomination": {
                        "type": "string",
                        "nullable": true
                      },
                      "obligor": {
                        "type": "string",
                        "nullable": true
                      },
                      "payments": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "description": "Shared input type for vault payment data. Used by both contract and swap\nflows to avoid duplication.\n",
                          "properties": {
                            "oracleAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleOwner": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeySender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSenderSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeyRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipientSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockReceiver": {
                              "type": "string",
                              "nullable": true
                            },
                            "linearVesting": {
                              "type": "boolean",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  },
                  "newInitiatorRepurchasePayments": {
                    "type": "object",
                    "required": [
                      "amount",
                      "payments"
                    ],
                    "properties": {
                      "amount": {
                        "type": "string",
                        "pattern": "^[0-9]+$",
                        "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                      },
                      "denomination": {
                        "type": "string",
                        "nullable": true
                      },
                      "obligor": {
                        "type": "string",
                        "nullable": true
                      },
                      "payments": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "description": "Shared input type for vault payment data. Used by both contract and swap\nflows to avoid duplication.\n",
                          "properties": {
                            "oracleAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleOwner": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeySender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSenderSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeyRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipientSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockReceiver": {
                              "type": "string",
                              "nullable": true
                            },
                            "linearVesting": {
                              "type": "boolean",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  },
                  "newCounterpartyRepurchasePayments": {
                    "type": "object",
                    "required": [
                      "amount",
                      "payments"
                    ],
                    "properties": {
                      "amount": {
                        "type": "string",
                        "pattern": "^[0-9]+$",
                        "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                      },
                      "denomination": {
                        "type": "string",
                        "nullable": true
                      },
                      "obligor": {
                        "type": "string",
                        "nullable": true
                      },
                      "payments": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "description": "Shared input type for vault payment data. Used by both contract and swap\nflows to avoid duplication.\n",
                          "properties": {
                            "oracleAddress": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleOwner": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeySender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueSenderSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleKeyRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipient": {
                              "type": "string",
                              "nullable": true
                            },
                            "oracleValueRecipientSecret": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockSender": {
                              "type": "string",
                              "nullable": true
                            },
                            "unlockReceiver": {
                              "type": "string",
                              "nullable": true
                            },
                            "linearVesting": {
                              "type": "boolean",
                              "nullable": true
                            }
                          }
                        }
                      }
                    }
                  },
                  "repurchaseObligationIds": {
                    "type": "array",
                    "nullable": true,
                    "items": {
                      "type": "string"
                    }
                  },
                  "repurchaseContractReferences": {
                    "type": "array",
                    "nullable": true,
                    "items": {
                      "type": "object",
                      "description": "Unified contract reference — can be either single contract or composed contract.\nExactly one of contractId or composedContractId must be provided.\n",
                      "properties": {
                        "contractId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Single contract ID (mutually exclusive with composedContractId)."
                        },
                        "composedContractId": {
                          "type": "string",
                          "nullable": true,
                          "description": "Composed contract ID (mutually exclusive with contractId)."
                        }
                      }
                    }
                  },
                  "repurchasePaymentIds": {
                    "type": "array",
                    "nullable": true,
                    "items": {
                      "type": "string"
                    }
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true
                  },
                  "name": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Roll a 30-day repo into a fresh 30-day repo with a new lender",
                  "value": {
                    "input": {
                      "oldSwapId": "SWAP-repo-2026-q1-001",
                      "newSwapId": "SWAP-repo-2026-q2-001",
                      "newCounterparty": "lender2@yieldfabric",
                      "newDeadline": "1738195200",
                      "newExpiry": "1740787200",
                      "newInitiatorRepurchasePayments": {
                        "amount": "1050",
                        "denomination": "USD",
                        "payments": [
                          {
                            "linearVesting": false
                          }
                        ]
                      },
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440240"
                    }
                  }
                },
                "with-upfront": {
                  "summary": "Roll forward and collect an explicit upfront from the new lender",
                  "value": {
                    "input": {
                      "oldSwapId": "SWAP-repo-2026-q1-001",
                      "newSwapId": "SWAP-repo-2026-q2-002",
                      "newCounterparty": "lender3@yieldfabric",
                      "newCounterpartyWalletId": "WALLET-lender3-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f",
                      "newDeadline": "1738195200",
                      "newExpiry": "1740787200",
                      "newInitiatorExpectedPayments": {
                        "amount": "1100",
                        "denomination": "USD",
                        "payments": [
                          {
                            "linearVesting": false
                          }
                        ]
                      },
                      "newInitiatorRepurchasePayments": {
                        "amount": "1155",
                        "denomination": "USD",
                        "payments": [
                          {
                            "linearVesting": false
                          }
                        ]
                      },
                      "name": "Q2 2026 Repo Roll",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440241"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "message",
                  "accountAddress",
                  "oldSwapId",
                  "newSwapId",
                  "messageId",
                  "transactionId",
                  "signature",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "oldSwapId": {
                    "type": "string"
                  },
                  "newSwapId": {
                    "type": "string"
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionId": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "signature": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Unknown old swap, old swap not in `ACTIVE` state, `newExpiry <= newDeadline`, etc."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "FORBIDDEN",
                "status": 403,
                "description": "Caller is not the initiator of `oldSwapId`."
              },
              {
                "code": "CONFLICT",
                "status": 409,
                "description": "`newSwapId` is already in use or `idempotencyKey` was reused with a different payload."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_initiateRoll",
              "resource_uri": "yf://swaps",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/swaps.yaml#/RollRepoResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: RollRepoInput!) { initiateRoll(input: $input) { success oldSwapId newSwapId messageId transactionId } }\",\"variables\":{\"input\":{\"oldSwapId\":\"SWAP-repo-2026-q1-001\",\"newSwapId\":\"SWAP-repo-2026-q2-001\",\"newCounterparty\":\"lender2@yieldfabric\",\"newDeadline\":\"1738195200\",\"newExpiry\":\"1740787200\",\"newInitiatorRepurchasePayments\":{\"amount\":\"1050\",\"denomination\":\"USD\",\"payments\":[{\"linearVesting\":false}]},\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440240\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: RollRepoInput!) { initiateRoll(input: $input) { success oldSwapId newSwapId messageId transactionId } }\",\n        \"variables\": {\n            \"input\": {\n                \"oldSwapId\": \"SWAP-repo-2026-q1-001\",\n                \"newSwapId\": \"SWAP-repo-2026-q2-001\",\n                \"newCounterparty\": \"lender2@yieldfabric\",\n                \"newDeadline\": \"1738195200\",\n                \"newExpiry\": \"1740787200\",\n                \"newInitiatorRepurchasePayments\": {\n                    \"amount\": \"1050\",\n                    \"denomination\": \"USD\",\n                    \"payments\": [{\"linearVesting\": False}],\n                },\n                \"idempotencyKey\": str(uuid.uuid4()),\n            }\n        },\n    },\n)\nprint(resp.json()[\"data\"][\"initiateRoll\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: RollRepoInput!) { initiateRoll(input: $input) { success oldSwapId newSwapId messageId transactionId } }`,\n  {\n    input: {\n      oldSwapId: \"SWAP-repo-2026-q1-001\",\n      newSwapId: \"SWAP-repo-2026-q2-001\",\n      newCounterparty: \"lender2@yieldfabric\",\n      newDeadline: \"1738195200\",\n      newExpiry: \"1740787200\",\n      newInitiatorRepurchasePayments: {\n        amount: \"1050\",\n        denomination: \"USD\",\n        payments: [{ linearVesting: false }],\n      },\n      idempotencyKey: crypto.randomUUID(),\n    },\n  }\n);\nconsole.log(data.initiateRoll);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation InitiateRoll($input: RollRepoInput!) {\n  initiateRoll(input: $input) {\n    success\n    oldSwapId\n    newSwapId\n    messageId\n    transactionId\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "completeRoll",
                "relation": "next"
              },
              {
                "operation": "repurchaseSwap",
                "relation": "alternative"
              },
              {
                "operation": "expireCollateral",
                "relation": "alternative"
              },
              {
                "guide": "swap-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "completeRoll",
            "kind": "mutation",
            "name": "completeRoll",
            "service": "yieldfabric-payments",
            "tags": [
              "Swaps"
            ],
            "summary": "New counterparty completes a roll, migrating collateral",
            "description": "Second step of a **repo roll**: the new counterparty pays the original\nrepurchase amount, the old repo is settled (`REPURCHASED`), and the\ncollateral migrates to the new repo (`ACTIVE`). The only required\ninput is `newSwapId` — the id of the pending repo created by\n`initiateRoll`.\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4) to make retries safe.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. The\ncaller must be the `newCounterparty` of the pending repo. When\n`walletId` is set, the new counterparty signs as that sub-account.\n\n**State transition (atomic, both occur):** old repo `ACTIVE → REPURCHASED`,\nnew repo `PENDING → ACTIVE`.\n\n**On-chain effect:** queues a `complete_roll` message. Response carries\n`newSwapId`, `messageId`, and `transactionId`.\n",
            "sdl": "mutation CompleteRoll($input: CompleteRollInput!) {\n  completeRoll(input: $input) {\n    success\n    newSwapId\n    messageId\n    transactionId\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "newSwapId"
                ],
                "properties": {
                  "newSwapId": {
                    "type": "string"
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  },
                  "walletId": {
                    "type": "string",
                    "nullable": true
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "New counterparty completes the roll",
                  "value": {
                    "input": {
                      "newSwapId": "SWAP-repo-2026-q2-001",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440250"
                    }
                  }
                },
                "with-wallet": {
                  "summary": "Complete the roll signed by a specific sub-account",
                  "value": {
                    "input": {
                      "newSwapId": "SWAP-repo-2026-q2-002",
                      "walletId": "WALLET-lender3-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440251"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "message",
                  "accountAddress",
                  "newSwapId",
                  "messageId",
                  "transactionId",
                  "signature",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "newSwapId": {
                    "type": "string"
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionId": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "signature": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Unknown `newSwapId`, new repo no longer `PENDING`, or insufficient funds for the repurchase payment."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "FORBIDDEN",
                "status": 403,
                "description": "Caller is not the `newCounterparty` of the pending repo."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_completeRoll",
              "resource_uri": "yf://swaps",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/swaps.yaml#/CompleteRollResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: CompleteRollInput!) { completeRoll(input: $input) { success newSwapId messageId transactionId } }\",\"variables\":{\"input\":{\"newSwapId\":\"SWAP-repo-2026-q2-001\",\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440250\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: CompleteRollInput!) { completeRoll(input: $input) { success newSwapId messageId transactionId } }\",\n        \"variables\": {\"input\": {\"newSwapId\": \"SWAP-repo-2026-q2-001\", \"idempotencyKey\": str(uuid.uuid4())}},\n    },\n)\nprint(resp.json()[\"data\"][\"completeRoll\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: CompleteRollInput!) { completeRoll(input: $input) { success newSwapId messageId transactionId } }`,\n  { input: { newSwapId: \"SWAP-repo-2026-q2-001\", idempotencyKey: crypto.randomUUID() } }\n);\nconsole.log(data.completeRoll);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation CompleteRoll($input: CompleteRollInput!) {\n  completeRoll(input: $input) {\n    success\n    newSwapId\n    messageId\n    transactionId\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "initiateRoll",
                "relation": "prerequisite"
              },
              {
                "operation": "completeSwap",
                "relation": "alternative"
              },
              {
                "guide": "swap-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "expireCollateral",
            "kind": "mutation",
            "name": "expireCollateral",
            "service": "yieldfabric-payments",
            "tags": [
              "Swaps"
            ],
            "summary": "Forfeit collateral on a repo whose expiry passed unrepurchased",
            "description": "Triggers forfeiture of locked collateral on an `ACTIVE` repo swap whose\n`expiry` has passed without repurchase. The underlying on-chain operation\nis permissionless: the caller triggers settlement but does not choose or\nnecessarily receive the collateral. The only required input is `swapId`.\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4) to make retries safe.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. Any\nauthenticated caller may trigger expiry. The caller signs with its own\nactive account on the JWT-selected chain; it does not impersonate either\nswap party.\n\n**State transition:** `ACTIVE → FORFEITED`. The collateral obligations\ntransfer to the dynamically resolved opposing position holder. In the\nstandard one-sided repo, initiator collateral goes to the current holder\nof the counterparty position, which can differ from the transaction caller\nand from the repo's original counterparty after a position transfer.\n\n**On-chain effect:** queues an `expire_collateral` message. Response\ncarries `swapId`, `messageId`, and `transactionId`.\n",
            "sdl": "mutation ExpireCollateral($input: ExpireCollateralInput!) {\n  expireCollateral(input: $input) {\n    success\n    swapId\n    messageId\n    transactionId\n    expireResult\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "description": "Expire collateral input.",
                "required": [
                  "swapId"
                ],
                "properties": {
                  "swapId": {
                    "type": "string"
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "When true, message is routed to manual signature (user signs via UX)\ninstead of automatic execution.\n"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Trigger collateral forfeiture after the repurchase window passed",
                  "value": {
                    "input": {
                      "swapId": "SWAP-repo-2026-q1-001",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440260"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "success",
                  "message",
                  "accountAddress",
                  "swapId",
                  "messageId",
                  "transactionId",
                  "signature",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "swapId": {
                    "type": "string"
                  },
                  "expireResult": {
                    "type": "string",
                    "nullable": true
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionId": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "signature": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Unknown swap, swap not `ACTIVE`, or `expiry` not yet passed."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "CHAIN_ACCOUNT_REQUIRED",
                "status": 409,
                "description": "The authenticated caller has no active account on the JWT-selected\nchain. Activate that entity on the returned chain, refresh the same\nactor's session, and retry once.\n"
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_expireCollateral",
              "resource_uri": "yf://swaps",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/swaps.yaml#/ExpireCollateralResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: ExpireCollateralInput!) { expireCollateral(input: $input) { success swapId messageId transactionId } }\",\"variables\":{\"input\":{\"swapId\":\"SWAP-repo-2026-q1-001\",\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440260\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: ExpireCollateralInput!) { expireCollateral(input: $input) { success swapId messageId transactionId } }\",\n        \"variables\": {\"input\": {\"swapId\": \"SWAP-repo-2026-q1-001\", \"idempotencyKey\": str(uuid.uuid4())}},\n    },\n)\nprint(resp.json()[\"data\"][\"expireCollateral\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: ExpireCollateralInput!) { expireCollateral(input: $input) { success swapId messageId transactionId } }`,\n  { input: { swapId: \"SWAP-repo-2026-q1-001\", idempotencyKey: crypto.randomUUID() } }\n);\nconsole.log(data.expireCollateral);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation ExpireCollateral($input: ExpireCollateralInput!) {\n  expireCollateral(input: $input) {\n    success\n    swapId\n    messageId\n    transactionId\n    expireResult\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "completeSwap",
                "relation": "prerequisite"
              },
              {
                "operation": "repurchaseSwap",
                "relation": "alternative"
              },
              {
                "guide": "swap-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "swapObligorPayment",
            "kind": "mutation",
            "name": "swapObligorPayment",
            "service": "yieldfabric-payments",
            "tags": [
              "Swaps"
            ],
            "summary": "Swap an obligor-backed payment for cash via the swap engine",
            "description": "Swap the right to a payment from a named `obligor` for cash, routed\nthrough the swap engine. Required inputs are `denomination`, `amount`\n(raw integer string at native scale), and `obligor` (entity name of\nthe obligor whose payment is being swapped). Pass `deadline` to bound\nthe swap-acceptance window.\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4) to make retries safe.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`. The\ncaller is identified from the JWT.\n\n**On-chain effect:** queues an obligor-payment swap; response shape\nmatches `CreateSwapResponse` and carries `swapId`, `messageId`, and\n`transactionId`.\n",
            "sdl": "mutation SwapObligorPayment($input: SwapObligorPaymentInput!) {\n  swapObligorPayment(input: $input) {\n    success\n    swapId\n    messageId\n    transactionId\n    timestamp\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "description": "Swap obligor payment input — swaps a payment with obligor for a payment\nwithout obligor.\n\nAllows a user to atomically swap a payment of a token with an obligor for\na payment of the same amount of the same token with obligor = null.\n",
                "required": [
                  "denomination",
                  "amount",
                  "obligor"
                ],
                "properties": {
                  "denomination": {
                    "type": "string"
                  },
                  "amount": {
                    "type": "string",
                    "pattern": "^[0-9]+$",
                    "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                  },
                  "obligor": {
                    "type": "string"
                  },
                  "deadline": {
                    "type": "string",
                    "nullable": true
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Swap a 1000 USD obligor payment for cash, 24-hour acceptance window",
                  "value": {
                    "input": {
                      "denomination": "USD",
                      "amount": "1000",
                      "obligor": "borrower-co@yieldfabric",
                      "deadline": "1735689600",
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440270"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "description": "Unified swap creation response.",
                "required": [
                  "success",
                  "message",
                  "accountAddress",
                  "swapId",
                  "counterparty",
                  "messageId",
                  "transactionId",
                  "signature",
                  "timestamp"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "swapId": {
                    "type": "string"
                  },
                  "counterparty": {
                    "type": "string"
                  },
                  "swapResult": {
                    "type": "string",
                    "nullable": true
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionId": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "signature": {
                    "type": "string",
                    "x-onchain": true
                  },
                  "timestamp": {
                    "type": "string",
                    "format": "date-time"
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Unknown obligor, unknown denomination, or invalid amount."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_swapObligorPayment",
              "resource_uri": "yf://swaps",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/swaps.yaml#/CreateSwapResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: SwapObligorPaymentInput!) { swapObligorPayment(input: $input) { success swapId messageId transactionId } }\",\"variables\":{\"input\":{\"denomination\":\"USD\",\"amount\":\"1000\",\"obligor\":\"borrower-co@yieldfabric\",\"deadline\":\"1735689600\",\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440270\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: SwapObligorPaymentInput!) { swapObligorPayment(input: $input) { success swapId messageId transactionId } }\",\n        \"variables\": {\n            \"input\": {\n                \"denomination\": \"USD\",\n                \"amount\": \"1000\",\n                \"obligor\": \"borrower-co@yieldfabric\",\n                \"deadline\": \"1735689600\",\n                \"idempotencyKey\": str(uuid.uuid4()),\n            }\n        },\n    },\n)\nprint(resp.json()[\"data\"][\"swapObligorPayment\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: SwapObligorPaymentInput!) { swapObligorPayment(input: $input) { success swapId messageId transactionId } }`,\n  {\n    input: {\n      denomination: \"USD\",\n      amount: \"1000\",\n      obligor: \"borrower-co@yieldfabric\",\n      deadline: \"1735689600\",\n      idempotencyKey: crypto.randomUUID(),\n    },\n  }\n);\nconsole.log(data.swapObligorPayment);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation SwapObligorPayment($input: SwapObligorPaymentInput!) {\n  swapObligorPayment(input: $input) {\n    success\n    swapId\n    messageId\n    transactionId\n    timestamp\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "createSwap",
                "relation": "alternative"
              },
              {
                "operation": "completeSwap",
                "relation": "next"
              },
              {
                "guide": "swap-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "executeComposedOperations",
            "kind": "mutation",
            "name": "executeComposedOperations",
            "service": "yieldfabric-payments",
            "tags": [
              "Composed"
            ],
            "summary": "Execute multiple operations atomically as one batch",
            "description": "Compose contract / payment / swap operations into one atomic batch that\nsucceeds or fails together. The only required input is `operations` —\nan ordered list of `{ operationType, operationData }` items.\n\n`operationType` is one of:\n`CreateObligation`, `AcceptObligation`, `TransferObligation`,\n`CancelObligation`, `Deposit`, `InstantSend`, `Withdraw`, `CreateSwap`,\n`CompleteSwap`, `CancelSwap`.\n\n`operationData` is the operation-specific JSON shape (the same fields as\nthe standalone mutation's `input`, just nested under JSON instead of a\ntyped input).\n\nSet `composedContractName` (and optionally `composedContractDescription`)\nto bundle the resulting obligations under a single `COMPOSED-CONTRACT-<id>`\nwrapper. Omit to run a flat batch with no wrapper.\n\n**Idempotency:** pass `idempotencyKey` (UUIDv4) at the top level for the\nwhole batch; the same key returns the same composed result without\nre-executing the legs.\n\n**Auth:** bearer JWT, `aud` includes `payments` or `default`.\n\n**On-chain effect:** queues a single composed message. The enqueue response\ncarries `transactionId` (the stable logical anchor), `composedId` (batch UUID), `composedContractId`\n(the persistent wrapper if a name was set), `operationCount`, and\nper-operation results in `operationResults` for variable substitution\nin downstream deal-plan steps.\n",
            "sdl": "mutation ExecuteComposedOperations($input: ComposedOperationInput!) {\n  executeComposedOperations(input: $input) {\n    success\n    messageId\n    transactionId\n    composedId\n    composedContractId\n    operationCount\n    operationResults { operationType paymentId contractId }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "description": "Input for composed operation execution.",
                "required": [
                  "operations"
                ],
                "properties": {
                  "operations": {
                    "type": "array",
                    "description": "List of operations to execute atomically.",
                    "items": {
                      "type": "object",
                      "description": "A single operation within a composed transaction.\n\nNote: This is the GraphQL version of the ComposedOperation type from MQ.\nThe GraphQL layer uses `OperationType` enum while MQ uses `MessageType` enum.\n",
                      "required": [
                        "operationType",
                        "operationData"
                      ],
                      "properties": {
                        "operationType": {
                          "type": "string",
                          "description": "Supported operation types for composed execution.",
                          "enum": [
                            "CreateObligation",
                            "AcceptObligation",
                            "TransferObligation",
                            "CancelObligation",
                            "Deposit",
                            "InstantSend",
                            "Withdraw",
                            "CreateSwap",
                            "CompleteSwap",
                            "CancelSwap"
                          ]
                        },
                        "operationData": {
                          "description": "Arbitrary JSON value (object, array, scalar, or null)."
                        }
                      }
                    }
                  },
                  "idempotencyKey": {
                    "type": "string",
                    "nullable": true,
                    "description": "Optional idempotency key for the entire composed batch."
                  },
                  "requireManualSignature": {
                    "type": "boolean",
                    "nullable": true,
                    "description": "When true, the composed message is routed to manual signature\n(user signs via UX) instead of automatic execution.\n"
                  },
                  "composedContractName": {
                    "type": "string",
                    "nullable": true,
                    "description": "When provided, the obligations created in this batch are bundled\nunder a `COMPOSED-CONTRACT-<id>` record carrying this name. The\nagents-side `create_composed_contract` task always passes this so\nthe wallet UX renders one composed bundle instead of N orphan\nobligations. Omit (or pass `None`) to skip wrapper creation —\ncallers that just want a batch of unrelated obligations don't\nneed the parent record.\n"
                  },
                  "composedContractDescription": {
                    "type": "string",
                    "nullable": true,
                    "description": "Optional description carried on the composed-contract wrapper\nalongside the name. Same gating: only used when\n`composedContractName` is provided.\n"
                  }
                }
              },
              "examples": {
                "deposit-then-send": {
                  "summary": "Deposit USD and immediately send a portion to alice — atomic",
                  "value": {
                    "input": {
                      "operations": [
                        {
                          "operationType": "Deposit",
                          "operationData": {
                            "assetId": "USD",
                            "amount": "1000"
                          }
                        },
                        {
                          "operationType": "InstantSend",
                          "operationData": {
                            "assetId": "USD",
                            "amount": "500",
                            "destinationId": "alice@yieldfabric"
                          }
                        }
                      ],
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440300"
                    }
                  }
                },
                "create-and-accept-obligation": {
                  "summary": "Create an obligation and accept it in one bundle, wrapped under a named composed contract",
                  "value": {
                    "input": {
                      "composedContractName": "Q4 2027 Invoice Bundle",
                      "composedContractDescription": "Auto-generated invoice + self-accept for testing",
                      "operations": [
                        {
                          "operationType": "CreateObligation",
                          "operationData": {
                            "counterpart": "bob@yieldfabric",
                            "denomination": "USD",
                            "notional": "5000",
                            "expiry": "1735603200"
                          }
                        },
                        {
                          "operationType": "AcceptObligation",
                          "operationData": {
                            "contractId": "CONTRACT-OBLIGATION-12345"
                          }
                        }
                      ],
                      "idempotencyKey": "550e8400-e29b-41d4-a716-446655440301"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "description": "Response from composed operation execution.",
                "required": [
                  "success",
                  "message",
                  "messageId",
                  "transactionId",
                  "composedId",
                  "accountAddress",
                  "operationCount",
                  "operationResults"
                ],
                "properties": {
                  "success": {
                    "type": "boolean"
                  },
                  "message": {
                    "type": "string"
                  },
                  "messageId": {
                    "type": "string",
                    "format": "uuid"
                  },
                  "transactionId": {
                    "type": "string",
                    "description": "Stable logical transaction anchor for this composed submission."
                  },
                  "composedId": {
                    "type": "string",
                    "description": "Operation-batch UUID. Just a transaction-grouping handle — distinct\nfrom `composedContractId` below. Kept for log correlation;\ndownstream deal-flow refs should target `composedContractId`\n(the persistent wrapper) instead.\n"
                  },
                  "composedContractId": {
                    "type": "string",
                    "nullable": true,
                    "description": "The persistent `COMPOSED-CONTRACT-<digits>` wrapper id that links\nthe per-leg obligations under one composed-contract record. This IS\nthe artefact downstream `$step.X.composed_contract_id` refs in deal\nplans expect to resolve to. Populated whenever the composed\noperation generates an obligation leg (always, in practice —\ncomposed_flow creates the wrapper up-front).\n"
                  },
                  "accountAddress": {
                    "type": "string"
                  },
                  "operationCount": {
                    "type": "integer"
                  },
                  "operationResults": {
                    "type": "array",
                    "description": "Individual operation results for variable substitution in subsequent commands.",
                    "items": {
                      "type": "object",
                      "description": "Individual operation result within a composed transaction.",
                      "required": [
                        "operationType",
                        "success"
                      ],
                      "properties": {
                        "operationType": {
                          "type": "string"
                        },
                        "success": {
                          "type": "boolean"
                        },
                        "message": {
                          "type": "string",
                          "nullable": true
                        },
                        "paymentId": {
                          "type": "string",
                          "nullable": true
                        },
                        "contractId": {
                          "type": "string",
                          "nullable": true
                        },
                        "amount": {
                          "type": "string",
                          "nullable": true
                        },
                        "idHash": {
                          "type": "string",
                          "nullable": true
                        },
                        "destinationId": {
                          "type": "string",
                          "nullable": true
                        },
                        "obligationId": {
                          "type": "string",
                          "nullable": true
                        },
                        "swapId": {
                          "type": "string",
                          "nullable": true
                        }
                      }
                    }
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Empty operations list, unknown `operationType`, or any leg fails validation."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "IDEMPOTENCY_CONFLICT",
                "status": 409,
                "description": "`idempotencyKey` was reused with a different payload."
              },
              {
                "code": "INTERNAL_ERROR",
                "status": 500,
                "description": "Atomic execution of one or more legs failed; the whole batch is rolled back."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_executeComposedOperations",
              "resource_uri": "yf://composed",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/composed.yaml#/ComposedOperationResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"query\":\"mutation($input: ComposedOperationInput!) { executeComposedOperations(input: $input) { success messageId composedId operationCount } }\",\"variables\":{\"input\":{\"operations\":[{\"operationType\":\"Deposit\",\"operationData\":{\"assetId\":\"USD\",\"amount\":\"1000\"}},{\"operationType\":\"InstantSend\",\"operationData\":{\"assetId\":\"USD\",\"amount\":\"500\",\"destinationId\":\"alice@yieldfabric\"}}],\"idempotencyKey\":\"550e8400-e29b-41d4-a716-446655440300\"}}}'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx, uuid\n\nresp = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"mutation($input: ComposedOperationInput!) { executeComposedOperations(input: $input) { success messageId composedId operationCount } }\",\n        \"variables\": {\n            \"input\": {\n                \"operations\": [\n                    {\n                        \"operationType\": \"Deposit\",\n                        \"operationData\": {\"assetId\": \"USD\", \"amount\": \"1000\"},\n                    },\n                    {\n                        \"operationType\": \"InstantSend\",\n                        \"operationData\": {\n                            \"assetId\": \"USD\",\n                            \"amount\": \"500\",\n                            \"destinationId\": \"alice@yieldfabric\",\n                        },\n                    },\n                ],\n                \"idempotencyKey\": str(uuid.uuid4()),\n            }\n        },\n    },\n)\nprint(resp.json()[\"data\"][\"executeComposedOperations\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`mutation($input: ComposedOperationInput!) { executeComposedOperations(input: $input) { success messageId composedId operationCount } }`,\n  {\n    input: {\n      operations: [\n        { operationType: \"Deposit\", operationData: { assetId: \"USD\", amount: \"1000\" } },\n        {\n          operationType: \"InstantSend\",\n          operationData: {\n            assetId: \"USD\",\n            amount: \"500\",\n            destinationId: \"alice@yieldfabric\",\n          },\n        },\n      ],\n      idempotencyKey: crypto.randomUUID(),\n    },\n  }\n);\nconsole.log(data.executeComposedOperations);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation ExecuteComposedOperations($input: ComposedOperationInput!) {\n  executeComposedOperations(input: $input) {\n    success\n    messageId\n    composedId\n    composedContractId\n    operationCount\n    operationResults { operationType paymentId contractId }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "createObligation",
                "relation": "alternative"
              },
              {
                "operation": "deposit",
                "relation": "alternative"
              },
              {
                "operation": "createSwap",
                "relation": "alternative"
              },
              {
                "guide": "composed-operations",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "interop_manifest",
            "kind": "query",
            "name": "interop_manifest",
            "service": "yieldfabric-payments",
            "tags": [
              "Interop"
            ],
            "summary": "Return the interop manifest JSON",
            "description": "Returns the full manifest JSON as served at\n`/.well-known/yieldfabric-service.json`. Useful when the caller already\nholds the endpoint URL but wants to avoid a separate HTTP fetch.\n\n**Auth:** **SIWE-authed** at the operation level — but this query takes\nno `auth` input because the manifest is intentionally public discovery\nmetadata. Note: the broader interop schema is SIWE-authed; this single\nread is the exception so any party can resolve the service's\ncapabilities and supported chains before initiating a SIWE handshake.\n\nCompanion to the on-chain `ServiceRegistry.sol` discovery contract: the\nmanifest carries the off-chain capability declaration that complements\nthe on-chain registration.\n",
            "sdl": "query InteropManifest {\n  interop_manifest\n}\n",
            "output": {
              "schema": {
                "type": "object",
                "description": "Response from `interop_manifest`. The manifest itself is returned as a\nstring (the GraphQL scalar is `String!`); the contents are the same JSON\nthat `/.well-known/yieldfabric-service.json` serves.\n",
                "required": [
                  "manifest"
                ],
                "properties": {
                  "manifest": {
                    "type": "string",
                    "description": "Stringified manifest JSON, same shape as the well-known file."
                  }
                }
              }
            },
            "security": [
              {
                "siweAuth": []
              }
            ],
            "errors": [
              {
                "code": "INTERNAL_ERROR",
                "status": 500,
                "description": "Manifest file is missing or unreadable on the server."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_interop_manifest",
              "resource_uri": "yf://interop/manifest",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/interop.yaml#/InteropManifestResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"query InteropManifest { interop_manifest }\"\n  }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nquery = \"query InteropManifest { interop_manifest }\"\nr = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    json={\"query\": query},\n)\nprint(r.json()[\"data\"][\"interop_manifest\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\");\n\nconst INTEROP_MANIFEST = gql`\n  query InteropManifest {\n    interop_manifest\n  }\n`;\n\nconst data = await client.request(INTEROP_MANIFEST);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "query InteropManifest {\n  interop_manifest\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "interop_listAnchors",
                "relation": "next"
              },
              {
                "operation": "interop_exportCredentials",
                "relation": "next"
              },
              {
                "guide": "interop",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "interop_listAnchors",
            "kind": "query",
            "name": "interop_listAnchors",
            "service": "yieldfabric-payments",
            "tags": [
              "Interop"
            ],
            "summary": "List anchors this service holds for an owner",
            "description": "Enumerate the anchors this service holds credentials for on behalf of\n`owner`. Returns anchors only — no plaintext, no ciphertext. The caller\nfollows up with `interop_exportCredentials` for the ones it wants.\n\nUse this as the discovery half of an owner-initiated migration: list\nfirst, then export the chosen anchors.\n\n**Auth:** **SIWE-authed.** The signature MUST be from `owner`. Standard\ncallee checks apply (signature recovers to `claimedAddress`, message\n`uri` matches this service's `interopEndpoint`, `chainId` is supported,\nmessage expires within 5 minutes, nonce not previously seen).\n",
            "sdl": "query InteropListAnchors($owner: Address!, $auth: AuthInput!) {\n  interop_listAnchors(owner: $owner, auth: $auth) {\n    chainId\n    contractAddress\n    tokenId\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "owner",
                  "auth"
                ],
                "properties": {
                  "owner": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]{40}$",
                    "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                  },
                  "auth": {
                    "type": "object",
                    "description": "Every interop mutation authenticates with a fresh SIWE message. Callees MUST:\n  * verify the signature recovers to `claimedAddress`\n  * verify `message.uri` equals this service's interopEndpoint\n  * verify `message.chainId` is one of the service's supportedChains\n  * verify `message.expirationTime - now <= 5 minutes`\n  * verify the nonce has not been seen before (replay protection)\n",
                    "required": [
                      "claimedAddress",
                      "message",
                      "signature"
                    ],
                    "properties": {
                      "claimedAddress": {
                        "type": "string",
                        "pattern": "^0x[0-9a-fA-F]{40}$",
                        "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                      },
                      "message": {
                        "type": "string",
                        "description": "Full EIP-4361 (Sign-In With Ethereum) message text."
                      },
                      "signature": {
                        "type": "string",
                        "pattern": "^0x[0-9a-fA-F]{130}$",
                        "description": "65-byte (130 hex chars after 0x) signature over a SIWEMessage."
                      }
                    }
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Owner lists their anchors on this service",
                  "value": {
                    "owner": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1",
                    "auth": {
                      "claimedAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1",
                      "message": "example.yieldfabric.com wants you to sign in with your Ethereum account:\n0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1\n\nURI: https://example.yieldfabric.com/graphql\nVersion: 1\nChain ID: 1\nNonce: 32891756\nIssued At: 2027-05-17T12:00:00Z\nExpiration Time: 2027-05-17T12:05:00Z\n",
                      "signature": "0x8a1ef84b62b39c8b1ae8e2c7a3a8b3c2d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a90123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "anchors"
                ],
                "properties": {
                  "anchors": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "description": "Uniquely identifies a confidential artifact across services via on-chain ids.",
                      "required": [
                        "chainId",
                        "contractAddress",
                        "tokenId"
                      ],
                      "properties": {
                        "chainId": {
                          "type": "integer"
                        },
                        "contractAddress": {
                          "type": "string",
                          "pattern": "^0x[0-9a-fA-F]{40}$",
                          "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                        },
                        "tokenId": {
                          "type": "string",
                          "description": "BigUint as decimal string (obligations, swaps, etc.)."
                        }
                      }
                    }
                  }
                }
              }
            },
            "security": [
              {
                "siweAuth": []
              }
            ],
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Malformed SIWE message (URI, chainId, or expiry mismatch)."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "SIWE signature does not recover to `claimedAddress`, or the recovered address differs from `owner`."
              },
              {
                "code": "RATE_LIMITED",
                "status": 429,
                "description": "Service-side rate limit on anchor enumeration."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_interop_listAnchors",
              "resource_uri": "yf://interop/anchors",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/interop.yaml#/InteropListAnchorsResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"query InteropListAnchors($owner: Address!, $auth: AuthInput!) { interop_listAnchors(owner: $owner, auth: $auth) { chainId contractAddress tokenId } }\",\n    \"variables\": {\n      \"owner\": \"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1\",\n      \"auth\": { \"claimedAddress\": \"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1\", \"message\": \"...SIWE...\", \"signature\": \"0x...\" }\n    }\n  }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nquery = \"\"\"\nquery InteropListAnchors($owner: Address!, $auth: AuthInput!) {\n  interop_listAnchors(owner: $owner, auth: $auth) {\n    chainId\n    contractAddress\n    tokenId\n  }\n}\n\"\"\"\nvariables = {\n    \"owner\": \"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1\",\n    \"auth\": {\n        \"claimedAddress\": \"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1\",\n        \"message\": SIWE_MESSAGE,\n        \"signature\": SIWE_SIG,\n    },\n}\nr = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    json={\"query\": query, \"variables\": variables},\n)\nprint(r.json()[\"data\"][\"interop_listAnchors\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\");\n\nconst LIST_ANCHORS = gql`\n  query InteropListAnchors($owner: Address!, $auth: AuthInput!) {\n    interop_listAnchors(owner: $owner, auth: $auth) {\n      chainId\n      contractAddress\n      tokenId\n    }\n  }\n`;\n\nconst data = await client.request(LIST_ANCHORS, {\n  owner: \"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1\",\n  auth: {\n    claimedAddress: \"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1\",\n    message: SIWE_MESSAGE,\n    signature: SIWE_SIG,\n  },\n});\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "query InteropListAnchors($owner: Address!, $auth: AuthInput!) {\n  interop_listAnchors(owner: $owner, auth: $auth) {\n    chainId\n    contractAddress\n    tokenId\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "interop_exportCredentials",
                "relation": "next"
              },
              {
                "operation": "interop_manifest",
                "relation": "prev"
              },
              {
                "guide": "interop",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "interop_exportCredentials",
            "kind": "mutation",
            "name": "interop_exportCredentials",
            "service": "yieldfabric-payments",
            "tags": [
              "Interop"
            ],
            "summary": "Export an owner's credentials as a portable encrypted bundle",
            "description": "Owner pulls their own credentials from this service, encrypted to\n`recipientPubkey`. Typically `recipientPubkey` is the owner's wallet\npubkey, so the same key that owns the NFTs decrypts the export.\n\n**Service MUST:**\n- verify SIWE signature comes from `owner`\n- verify on-chain ownership for each anchor (owner matches the current\n  NFT holder)\n- refuse anchors not owned by `owner`\n- encrypt each credential JSON to `recipientPubkey` with ECIES\n- sign each envelope with the service operator key\n\n**Auth:** **SIWE-authed.** Standard callee checks apply (signature,\nURI, chainId, expiry, nonce).\n\n**Idempotency:** safe to retry — repeated calls return fresh ciphertext\nfor the same plaintext (the plaintextHash lets recipients dedupe).\n",
            "sdl": "mutation InteropExportCredentials(\n  $owner: Address!\n  $recipientPubkey: Hex!\n  $anchors: [ChainAnchorInput!]!\n  $auth: AuthInput!\n) {\n  interop_exportCredentials(\n    owner: $owner\n    recipientPubkey: $recipientPubkey\n    anchors: $anchors\n    auth: $auth\n  ) {\n    owner\n    recipientPubkey\n    bundleVersion\n    obligationCredentials {\n      anchor { chainId contractAddress tokenId }\n      blob { ciphertext plaintextHash serviceSignature serviceOperator schemaVersion exportedAt }\n    }\n    composedStructures {\n      rootAnchors { chainId contractAddress tokenId }\n      blob { ciphertext plaintextHash serviceSignature serviceOperator schemaVersion exportedAt }\n    }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "owner",
                  "recipientPubkey",
                  "anchors",
                  "auth"
                ],
                "properties": {
                  "owner": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]{40}$",
                    "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                  },
                  "recipientPubkey": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]*$",
                    "description": "0x-prefixed hex string of arbitrary length."
                  },
                  "anchors": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "chainId",
                        "contractAddress",
                        "tokenId"
                      ],
                      "properties": {
                        "chainId": {
                          "type": "integer"
                        },
                        "contractAddress": {
                          "type": "string",
                          "pattern": "^0x[0-9a-fA-F]{40}$",
                          "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                        },
                        "tokenId": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "auth": {
                    "type": "object",
                    "description": "Every interop mutation authenticates with a fresh SIWE message. Callees MUST:\n  * verify the signature recovers to `claimedAddress`\n  * verify `message.uri` equals this service's interopEndpoint\n  * verify `message.chainId` is one of the service's supportedChains\n  * verify `message.expirationTime - now <= 5 minutes`\n  * verify the nonce has not been seen before (replay protection)\n",
                    "required": [
                      "claimedAddress",
                      "message",
                      "signature"
                    ],
                    "properties": {
                      "claimedAddress": {
                        "type": "string",
                        "pattern": "^0x[0-9a-fA-F]{40}$",
                        "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                      },
                      "message": {
                        "type": "string",
                        "description": "Full EIP-4361 (Sign-In With Ethereum) message text."
                      },
                      "signature": {
                        "type": "string",
                        "pattern": "^0x[0-9a-fA-F]{130}$",
                        "description": "65-byte (130 hex chars after 0x) signature over a SIWEMessage."
                      }
                    }
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Owner exports two obligation anchors to their own wallet pubkey",
                  "value": {
                    "owner": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1",
                    "recipientPubkey": "0x04abcd1234ef567890abcd1234ef567890abcd1234ef567890abcd1234ef567890abcd1234ef567890abcd1234ef567890abcd1234ef567890abcd1234ef5678",
                    "anchors": [
                      {
                        "chainId": 1,
                        "contractAddress": "0x0123456789abcdef0123456789abcdef01234567",
                        "tokenId": "42"
                      },
                      {
                        "chainId": 1,
                        "contractAddress": "0x0123456789abcdef0123456789abcdef01234567",
                        "tokenId": "43"
                      }
                    ],
                    "auth": {
                      "claimedAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1",
                      "message": "...SIWE message...",
                      "signature": "0x8a1ef84b62b39c8b1ae8e2c7a3a8b3c2d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a90123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "owner",
                  "recipientPubkey",
                  "obligationCredentials",
                  "composedStructures",
                  "bundleVersion"
                ],
                "properties": {
                  "owner": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]{40}$",
                    "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                  },
                  "recipientPubkey": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]*$",
                    "description": "0x-prefixed hex string of arbitrary length."
                  },
                  "obligationCredentials": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "anchor",
                        "blob"
                      ],
                      "properties": {
                        "anchor": {
                          "type": "object",
                          "description": "Uniquely identifies a confidential artifact across services via on-chain ids.",
                          "required": [
                            "chainId",
                            "contractAddress",
                            "tokenId"
                          ],
                          "properties": {
                            "chainId": {
                              "type": "integer"
                            },
                            "contractAddress": {
                              "type": "string",
                              "pattern": "^0x[0-9a-fA-F]{40}$",
                              "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                            },
                            "tokenId": {
                              "type": "string",
                              "description": "BigUint as decimal string (obligations, swaps, etc.)."
                            }
                          }
                        },
                        "blob": {
                          "type": "object",
                          "description": "A single ciphertext blob, encrypted with ECIES to `recipientPubkey`.\nThe recipient pubkey is typically fetched from\n`ConfidentialWallet.get_public_key` on chain, so encryption requires no\nkey exchange.\n",
                          "required": [
                            "ciphertext",
                            "plaintextHash",
                            "serviceSignature",
                            "serviceOperator",
                            "schemaVersion",
                            "exportedAt"
                          ],
                          "properties": {
                            "ciphertext": {
                              "type": "string",
                              "description": "Base64-encoded ECIES ciphertext."
                            },
                            "plaintextHash": {
                              "type": "string",
                              "pattern": "^0x[0-9a-fA-F]*$",
                              "description": "0x-prefixed hex string of arbitrary length."
                            },
                            "serviceSignature": {
                              "type": "string",
                              "pattern": "^0x[0-9a-fA-F]*$",
                              "description": "0x-prefixed hex string of arbitrary length."
                            },
                            "serviceOperator": {
                              "type": "string",
                              "pattern": "^0x[0-9a-fA-F]{40}$",
                              "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                            },
                            "schemaVersion": {
                              "type": "string",
                              "description": "Schema version tag — currently `\"yf-interop-v1\"`."
                            },
                            "exportedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      }
                    }
                  },
                  "composedStructures": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "description": "Composed-contract structure (parent/child hierarchy of obligations forming\na repo, contingent, etc.). The plaintext inside `blob` is a JSON document\nof the RDF tree with ChainAnchor refs instead of service-local UUIDs.\n",
                      "required": [
                        "rootAnchors",
                        "blob"
                      ],
                      "properties": {
                        "rootAnchors": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "description": "Uniquely identifies a confidential artifact across services via on-chain ids.",
                            "required": [
                              "chainId",
                              "contractAddress",
                              "tokenId"
                            ],
                            "properties": {
                              "chainId": {
                                "type": "integer"
                              },
                              "contractAddress": {
                                "type": "string",
                                "pattern": "^0x[0-9a-fA-F]{40}$",
                                "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                              },
                              "tokenId": {
                                "type": "string",
                                "description": "BigUint as decimal string (obligations, swaps, etc.)."
                              }
                            }
                          }
                        },
                        "blob": {
                          "type": "object",
                          "description": "A single ciphertext blob, encrypted with ECIES to `recipientPubkey`.\nThe recipient pubkey is typically fetched from\n`ConfidentialWallet.get_public_key` on chain, so encryption requires no\nkey exchange.\n",
                          "required": [
                            "ciphertext",
                            "plaintextHash",
                            "serviceSignature",
                            "serviceOperator",
                            "schemaVersion",
                            "exportedAt"
                          ],
                          "properties": {
                            "ciphertext": {
                              "type": "string",
                              "description": "Base64-encoded ECIES ciphertext."
                            },
                            "plaintextHash": {
                              "type": "string",
                              "pattern": "^0x[0-9a-fA-F]*$",
                              "description": "0x-prefixed hex string of arbitrary length."
                            },
                            "serviceSignature": {
                              "type": "string",
                              "pattern": "^0x[0-9a-fA-F]*$",
                              "description": "0x-prefixed hex string of arbitrary length."
                            },
                            "serviceOperator": {
                              "type": "string",
                              "pattern": "^0x[0-9a-fA-F]{40}$",
                              "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                            },
                            "schemaVersion": {
                              "type": "string",
                              "description": "Schema version tag — currently `\"yf-interop-v1\"`."
                            },
                            "exportedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            }
                          }
                        }
                      }
                    }
                  },
                  "bundleVersion": {
                    "type": "string",
                    "description": "Bundle format tag — currently `\"yf-bundle-v1\"`."
                  }
                }
              }
            },
            "security": [
              {
                "siweAuth": []
              }
            ],
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Malformed SIWE message, malformed pubkey, or empty `anchors` list."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "SIWE signature does not recover to `owner`."
              },
              {
                "code": "FORBIDDEN",
                "status": 403,
                "description": "One or more anchors are not currently owned on chain by `owner`."
              },
              {
                "code": "NOT_FOUND",
                "status": 404,
                "description": "One or more anchors are unknown to this service."
              },
              {
                "code": "INTERNAL_ERROR",
                "status": 500,
                "description": "ECIES encryption or operator signing failed."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_interop_exportCredentials",
              "resource_uri": "yf://interop/bundle",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/interop.yaml#/InteropExportCredentialsResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"mutation InteropExportCredentials($owner: Address!, $recipientPubkey: Hex!, $anchors: [ChainAnchorInput!]!, $auth: AuthInput!) { interop_exportCredentials(owner: $owner, recipientPubkey: $recipientPubkey, anchors: $anchors, auth: $auth) { owner bundleVersion } }\",\n    \"variables\": {\n      \"owner\": \"0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1\",\n      \"recipientPubkey\": \"0x04abcd...\",\n      \"anchors\": [{ \"chainId\": 1, \"contractAddress\": \"0x0123...4567\", \"tokenId\": \"42\" }],\n      \"auth\": { \"claimedAddress\": \"0x742d...\", \"message\": \"...SIWE...\", \"signature\": \"0x...\" }\n    }\n  }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nquery = \"\"\"\nmutation InteropExportCredentials(\n  $owner: Address!\n  $recipientPubkey: Hex!\n  $anchors: [ChainAnchorInput!]!\n  $auth: AuthInput!\n) {\n  interop_exportCredentials(\n    owner: $owner\n    recipientPubkey: $recipientPubkey\n    anchors: $anchors\n    auth: $auth\n  ) {\n    owner\n    bundleVersion\n    obligationCredentials { anchor { tokenId } }\n  }\n}\n\"\"\"\nr = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    json={\"query\": query, \"variables\": variables},\n)\nprint(r.json()[\"data\"][\"interop_exportCredentials\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\");\n\nconst EXPORT_CREDENTIALS = gql`\n  mutation InteropExportCredentials(\n    $owner: Address!\n    $recipientPubkey: Hex!\n    $anchors: [ChainAnchorInput!]!\n    $auth: AuthInput!\n  ) {\n    interop_exportCredentials(\n      owner: $owner\n      recipientPubkey: $recipientPubkey\n      anchors: $anchors\n      auth: $auth\n    ) {\n      owner\n      bundleVersion\n    }\n  }\n`;\n\nconst data = await client.request(EXPORT_CREDENTIALS, variables);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation InteropExportCredentials(\n  $owner: Address!\n  $recipientPubkey: Hex!\n  $anchors: [ChainAnchorInput!]!\n  $auth: AuthInput!\n) {\n  interop_exportCredentials(\n    owner: $owner\n    recipientPubkey: $recipientPubkey\n    anchors: $anchors\n    auth: $auth\n  ) {\n    owner\n    recipientPubkey\n    bundleVersion\n    obligationCredentials {\n      anchor { chainId contractAddress tokenId }\n      blob { ciphertext plaintextHash serviceSignature serviceOperator schemaVersion exportedAt }\n    }\n    composedStructures {\n      rootAnchors { chainId contractAddress tokenId }\n      blob { ciphertext plaintextHash serviceSignature serviceOperator schemaVersion exportedAt }\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "interop_listAnchors",
                "relation": "prev"
              },
              {
                "operation": "interop_importBundle",
                "relation": "next"
              },
              {
                "operation": "interop_fetchForRecipient",
                "relation": "alternative"
              },
              {
                "guide": "interop",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "interop_importBundle",
            "kind": "mutation",
            "name": "interop_importBundle",
            "service": "yieldfabric-payments",
            "tags": [
              "Interop"
            ],
            "summary": "Import a previously exported credential bundle",
            "description": "Owner pushes a previously exported bundle into this service.\n\n**Service MUST:**\n- verify SIWE signature comes from `owner`\n- for each envelope: verify `serviceSignature` via `ServiceRegistry`\n  (ensure `serviceOperator` corresponds to a registered, active service\n  whose `supportedChains` include the anchor's `chainId`)\n- decrypt ciphertext (either with the owner's encryption keystore held\n  by this service, or by requesting decryption from the auth service)\n- verify `plaintextHash` matches the decrypted bytes\n- persist credential JSON keyed by `(chainId, contractAddress, tokenId)`\n- rebuild composed-contract hierarchy from decrypted structures\n- on rebuild, re-anchor composed tree references to on-chain ids\n\nPartial success is the norm: the response separates `imported`,\n`skipped` (already present, same plaintextHash), and `failed` (with\nper-envelope reasons such as `bad-service-signature`, `owner-mismatch`,\n`decrypt-failed`).\n\n**Auth:** **SIWE-authed.** Standard callee checks apply.\n\n**Idempotency:** safe to retry — re-importing a bundle whose envelopes\nare already present increments `skipped` rather than re-persisting.\n",
            "sdl": "mutation InteropImportBundle($bundle: PortableBundleInput!, $auth: AuthInput!) {\n  interop_importBundle(bundle: $bundle, auth: $auth) {\n    imported\n    skipped\n    failed {\n      anchor { chainId contractAddress tokenId }\n      reason\n    }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "bundle",
                  "auth"
                ],
                "properties": {
                  "bundle": {
                    "type": "object",
                    "required": [
                      "owner",
                      "recipientPubkey",
                      "obligationCredentials",
                      "composedStructures",
                      "bundleVersion"
                    ],
                    "properties": {
                      "owner": {
                        "type": "string",
                        "pattern": "^0x[0-9a-fA-F]{40}$",
                        "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                      },
                      "recipientPubkey": {
                        "type": "string",
                        "pattern": "^0x[0-9a-fA-F]*$",
                        "description": "0x-prefixed hex string of arbitrary length."
                      },
                      "obligationCredentials": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "required": [
                            "anchor",
                            "blob"
                          ],
                          "properties": {
                            "anchor": {
                              "type": "object",
                              "required": [
                                "chainId",
                                "contractAddress",
                                "tokenId"
                              ],
                              "properties": {
                                "chainId": {
                                  "type": "integer"
                                },
                                "contractAddress": {
                                  "type": "string",
                                  "pattern": "^0x[0-9a-fA-F]{40}$",
                                  "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                                },
                                "tokenId": {
                                  "type": "string"
                                }
                              }
                            },
                            "blob": {
                              "type": "object",
                              "required": [
                                "ciphertext",
                                "plaintextHash",
                                "serviceSignature",
                                "serviceOperator",
                                "schemaVersion",
                                "exportedAt"
                              ],
                              "properties": {
                                "ciphertext": {
                                  "type": "string"
                                },
                                "plaintextHash": {
                                  "type": "string",
                                  "pattern": "^0x[0-9a-fA-F]*$",
                                  "description": "0x-prefixed hex string of arbitrary length."
                                },
                                "serviceSignature": {
                                  "type": "string",
                                  "pattern": "^0x[0-9a-fA-F]*$",
                                  "description": "0x-prefixed hex string of arbitrary length."
                                },
                                "serviceOperator": {
                                  "type": "string",
                                  "pattern": "^0x[0-9a-fA-F]{40}$",
                                  "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                                },
                                "schemaVersion": {
                                  "type": "string"
                                },
                                "exportedAt": {
                                  "type": "string",
                                  "format": "date-time",
                                  "description": "ISO-8601 datetime (UTC)."
                                }
                              }
                            }
                          }
                        }
                      },
                      "composedStructures": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "required": [
                            "rootAnchors",
                            "blob"
                          ],
                          "properties": {
                            "rootAnchors": {
                              "type": "array",
                              "items": {
                                "type": "object",
                                "required": [
                                  "chainId",
                                  "contractAddress",
                                  "tokenId"
                                ],
                                "properties": {
                                  "chainId": {
                                    "type": "integer"
                                  },
                                  "contractAddress": {
                                    "type": "string",
                                    "pattern": "^0x[0-9a-fA-F]{40}$",
                                    "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                                  },
                                  "tokenId": {
                                    "type": "string"
                                  }
                                }
                              }
                            },
                            "blob": {
                              "type": "object",
                              "required": [
                                "ciphertext",
                                "plaintextHash",
                                "serviceSignature",
                                "serviceOperator",
                                "schemaVersion",
                                "exportedAt"
                              ],
                              "properties": {
                                "ciphertext": {
                                  "type": "string"
                                },
                                "plaintextHash": {
                                  "type": "string",
                                  "pattern": "^0x[0-9a-fA-F]*$",
                                  "description": "0x-prefixed hex string of arbitrary length."
                                },
                                "serviceSignature": {
                                  "type": "string",
                                  "pattern": "^0x[0-9a-fA-F]*$",
                                  "description": "0x-prefixed hex string of arbitrary length."
                                },
                                "serviceOperator": {
                                  "type": "string",
                                  "pattern": "^0x[0-9a-fA-F]{40}$",
                                  "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                                },
                                "schemaVersion": {
                                  "type": "string"
                                },
                                "exportedAt": {
                                  "type": "string",
                                  "format": "date-time",
                                  "description": "ISO-8601 datetime (UTC)."
                                }
                              }
                            }
                          }
                        }
                      },
                      "bundleVersion": {
                        "type": "string"
                      }
                    }
                  },
                  "auth": {
                    "type": "object",
                    "description": "Every interop mutation authenticates with a fresh SIWE message. Callees MUST:\n  * verify the signature recovers to `claimedAddress`\n  * verify `message.uri` equals this service's interopEndpoint\n  * verify `message.chainId` is one of the service's supportedChains\n  * verify `message.expirationTime - now <= 5 minutes`\n  * verify the nonce has not been seen before (replay protection)\n",
                    "required": [
                      "claimedAddress",
                      "message",
                      "signature"
                    ],
                    "properties": {
                      "claimedAddress": {
                        "type": "string",
                        "pattern": "^0x[0-9a-fA-F]{40}$",
                        "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                      },
                      "message": {
                        "type": "string",
                        "description": "Full EIP-4361 (Sign-In With Ethereum) message text."
                      },
                      "signature": {
                        "type": "string",
                        "pattern": "^0x[0-9a-fA-F]{130}$",
                        "description": "65-byte (130 hex chars after 0x) signature over a SIWEMessage."
                      }
                    }
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Owner imports a one-anchor bundle they previously exported elsewhere",
                  "value": {
                    "bundle": {
                      "owner": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1",
                      "recipientPubkey": "0x04abcd1234ef567890abcd1234ef567890abcd1234ef567890abcd1234ef567890abcd1234ef567890abcd1234ef567890abcd1234ef567890abcd1234ef5678",
                      "bundleVersion": "yf-bundle-v1",
                      "obligationCredentials": [
                        {
                          "anchor": {
                            "chainId": 1,
                            "contractAddress": "0x0123456789abcdef0123456789abcdef01234567",
                            "tokenId": "42"
                          },
                          "blob": {
                            "ciphertext": "BASE64-ECIES-CIPHERTEXT",
                            "plaintextHash": "0xfeedface0123456789abcdef0123456789abcdef0123456789abcdef01234567",
                            "serviceSignature": "0xdeadbeef...",
                            "serviceOperator": "0xa0b1c2d3e4f5061728394a5b6c7d8e9f01234567",
                            "schemaVersion": "yf-interop-v1",
                            "exportedAt": "2027-05-17T11:55:00Z"
                          }
                        }
                      ],
                      "composedStructures": []
                    },
                    "auth": {
                      "claimedAddress": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb1",
                      "message": "...SIWE message...",
                      "signature": "0x8a1ef84b62b39c8b1ae8e2c7a3a8b3c2d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a90123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "imported",
                  "skipped",
                  "failed"
                ],
                "properties": {
                  "imported": {
                    "type": "integer"
                  },
                  "skipped": {
                    "type": "integer",
                    "description": "Already present, same plaintextHash."
                  },
                  "failed": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "anchor",
                        "reason"
                      ],
                      "properties": {
                        "anchor": {
                          "type": "object",
                          "description": "Uniquely identifies a confidential artifact across services via on-chain ids.",
                          "required": [
                            "chainId",
                            "contractAddress",
                            "tokenId"
                          ],
                          "properties": {
                            "chainId": {
                              "type": "integer"
                            },
                            "contractAddress": {
                              "type": "string",
                              "pattern": "^0x[0-9a-fA-F]{40}$",
                              "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                            },
                            "tokenId": {
                              "type": "string",
                              "description": "BigUint as decimal string (obligations, swaps, etc.)."
                            }
                          }
                        },
                        "reason": {
                          "type": "string",
                          "description": "Failure reason — e.g. `\"bad-service-signature\"`, `\"owner-mismatch\"`,\n`\"decrypt-failed\"`.\n"
                        }
                      }
                    }
                  }
                }
              }
            },
            "security": [
              {
                "siweAuth": []
              }
            ],
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Malformed bundle (unknown `bundleVersion`, mismatched envelope shape, malformed SIWE)."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "SIWE signature does not recover to the bundle's `owner`."
              },
              {
                "code": "INTERNAL_ERROR",
                "status": 500,
                "description": "Decryption or persistence layer failed for the whole bundle (per-envelope failures are reported in `failed[]`, not raised as errors)."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_interop_importBundle",
              "resource_uri": "yf://interop/bundle",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/interop.yaml#/InteropImportBundleResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"mutation InteropImportBundle($bundle: PortableBundleInput!, $auth: AuthInput!) { interop_importBundle(bundle: $bundle, auth: $auth) { imported skipped failed { reason anchor { tokenId } } } }\",\n    \"variables\": { \"bundle\": { \"owner\": \"0x742d...\", \"recipientPubkey\": \"0x04...\", \"bundleVersion\": \"yf-bundle-v1\", \"obligationCredentials\": [], \"composedStructures\": [] }, \"auth\": {} }\n  }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nquery = \"\"\"\nmutation InteropImportBundle($bundle: PortableBundleInput!, $auth: AuthInput!) {\n  interop_importBundle(bundle: $bundle, auth: $auth) {\n    imported\n    skipped\n    failed { anchor { chainId contractAddress tokenId } reason }\n  }\n}\n\"\"\"\nr = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    json={\"query\": query, \"variables\": variables},\n)\nprint(r.json()[\"data\"][\"interop_importBundle\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\");\n\nconst IMPORT_BUNDLE = gql`\n  mutation InteropImportBundle($bundle: PortableBundleInput!, $auth: AuthInput!) {\n    interop_importBundle(bundle: $bundle, auth: $auth) {\n      imported\n      skipped\n      failed { anchor { chainId contractAddress tokenId } reason }\n    }\n  }\n`;\n\nconst data = await client.request(IMPORT_BUNDLE, variables);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation InteropImportBundle($bundle: PortableBundleInput!, $auth: AuthInput!) {\n  interop_importBundle(bundle: $bundle, auth: $auth) {\n    imported\n    skipped\n    failed {\n      anchor { chainId contractAddress tokenId }\n      reason\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "interop_exportCredentials",
                "relation": "prev"
              },
              {
                "operation": "interop_listAnchors",
                "relation": "alternative"
              },
              {
                "operation": "interop_fetchForRecipient",
                "relation": "alternative"
              },
              {
                "guide": "interop",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "interop_fetchForRecipient",
            "kind": "mutation",
            "name": "interop_fetchForRecipient",
            "service": "yieldfabric-payments",
            "tags": [
              "Interop"
            ],
            "summary": "Counterparty fetches a credential they now own on chain",
            "description": "Called by another service (or a wallet client) to fetch the credential\nfor an anchor that the caller's user now owns on chain. This is the\nmechanism that lets Alice's service deliver a just-minted obligation\nto Bob's service.\n\n**Service MUST:**\n- verify SIWE signature comes from the CURRENT on-chain owner of\n  `anchor`\n- refuse if the requester is not the current on-chain owner\n- encrypt the credential to `recipientPubkey` (typically the owner's\n  wallet pubkey)\n- sign the envelope with the service operator key\n\n**Service SHOULD** rate-limit per (anchor, requester) to discourage\nscraping.\n\n**Auth:** **SIWE-authed.** Distinct from `interop_exportCredentials` in\nthat the caller is not the original owner-of-record on this service —\nthey are the new on-chain owner who just received the NFT and is now\npulling the off-chain credential.\n",
            "sdl": "mutation InteropFetchForRecipient(\n  $anchor: ChainAnchorInput!\n  $recipientPubkey: Hex!\n  $auth: AuthInput!\n) {\n  interop_fetchForRecipient(\n    anchor: $anchor\n    recipientPubkey: $recipientPubkey\n    auth: $auth\n  ) {\n    anchor { chainId contractAddress tokenId }\n    blob {\n      ciphertext\n      plaintextHash\n      serviceSignature\n      serviceOperator\n      schemaVersion\n      exportedAt\n    }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "anchor",
                  "recipientPubkey",
                  "auth"
                ],
                "properties": {
                  "anchor": {
                    "type": "object",
                    "required": [
                      "chainId",
                      "contractAddress",
                      "tokenId"
                    ],
                    "properties": {
                      "chainId": {
                        "type": "integer"
                      },
                      "contractAddress": {
                        "type": "string",
                        "pattern": "^0x[0-9a-fA-F]{40}$",
                        "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                      },
                      "tokenId": {
                        "type": "string"
                      }
                    }
                  },
                  "recipientPubkey": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]*$",
                    "description": "0x-prefixed hex string of arbitrary length."
                  },
                  "auth": {
                    "type": "object",
                    "description": "Every interop mutation authenticates with a fresh SIWE message. Callees MUST:\n  * verify the signature recovers to `claimedAddress`\n  * verify `message.uri` equals this service's interopEndpoint\n  * verify `message.chainId` is one of the service's supportedChains\n  * verify `message.expirationTime - now <= 5 minutes`\n  * verify the nonce has not been seen before (replay protection)\n",
                    "required": [
                      "claimedAddress",
                      "message",
                      "signature"
                    ],
                    "properties": {
                      "claimedAddress": {
                        "type": "string",
                        "pattern": "^0x[0-9a-fA-F]{40}$",
                        "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                      },
                      "message": {
                        "type": "string",
                        "description": "Full EIP-4361 (Sign-In With Ethereum) message text."
                      },
                      "signature": {
                        "type": "string",
                        "pattern": "^0x[0-9a-fA-F]{130}$",
                        "description": "65-byte (130 hex chars after 0x) signature over a SIWEMessage."
                      }
                    }
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Bob fetches the credential for a token he now owns",
                  "value": {
                    "anchor": {
                      "chainId": 1,
                      "contractAddress": "0x0123456789abcdef0123456789abcdef01234567",
                      "tokenId": "42"
                    },
                    "recipientPubkey": "0x04abcd1234ef567890abcd1234ef567890abcd1234ef567890abcd1234ef567890abcd1234ef567890abcd1234ef567890abcd1234ef567890abcd1234ef5678",
                    "auth": {
                      "claimedAddress": "0xa1b2c3d4e5f60718293a4b5c6d7e8f9012345678",
                      "message": "...SIWE message from Bob...",
                      "signature": "0x8a1ef84b62b39c8b1ae8e2c7a3a8b3c2d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a90123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01"
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "anchor",
                  "blob"
                ],
                "properties": {
                  "anchor": {
                    "type": "object",
                    "description": "Uniquely identifies a confidential artifact across services via on-chain ids.",
                    "required": [
                      "chainId",
                      "contractAddress",
                      "tokenId"
                    ],
                    "properties": {
                      "chainId": {
                        "type": "integer"
                      },
                      "contractAddress": {
                        "type": "string",
                        "pattern": "^0x[0-9a-fA-F]{40}$",
                        "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                      },
                      "tokenId": {
                        "type": "string",
                        "description": "BigUint as decimal string (obligations, swaps, etc.)."
                      }
                    }
                  },
                  "blob": {
                    "type": "object",
                    "description": "A single ciphertext blob, encrypted with ECIES to `recipientPubkey`.\nThe recipient pubkey is typically fetched from\n`ConfidentialWallet.get_public_key` on chain, so encryption requires no\nkey exchange.\n",
                    "required": [
                      "ciphertext",
                      "plaintextHash",
                      "serviceSignature",
                      "serviceOperator",
                      "schemaVersion",
                      "exportedAt"
                    ],
                    "properties": {
                      "ciphertext": {
                        "type": "string",
                        "description": "Base64-encoded ECIES ciphertext."
                      },
                      "plaintextHash": {
                        "type": "string",
                        "pattern": "^0x[0-9a-fA-F]*$",
                        "description": "0x-prefixed hex string of arbitrary length."
                      },
                      "serviceSignature": {
                        "type": "string",
                        "pattern": "^0x[0-9a-fA-F]*$",
                        "description": "0x-prefixed hex string of arbitrary length."
                      },
                      "serviceOperator": {
                        "type": "string",
                        "pattern": "^0x[0-9a-fA-F]{40}$",
                        "description": "0x-prefixed, EIP-55 checksummed 20-byte Ethereum address."
                      },
                      "schemaVersion": {
                        "type": "string",
                        "description": "Schema version tag — currently `\"yf-interop-v1\"`."
                      },
                      "exportedAt": {
                        "type": "string",
                        "format": "date-time",
                        "description": "ISO-8601 datetime (UTC)."
                      }
                    }
                  }
                }
              }
            },
            "security": [
              {
                "siweAuth": []
              }
            ],
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Malformed SIWE message or `recipientPubkey`."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "SIWE signature does not recover to `claimedAddress`."
              },
              {
                "code": "FORBIDDEN",
                "status": 403,
                "description": "Requester is not the current on-chain owner of `anchor`."
              },
              {
                "code": "NOT_FOUND",
                "status": 404,
                "description": "This service does not hold a credential for the given `anchor`."
              },
              {
                "code": "RATE_LIMITED",
                "status": 429,
                "description": "Per-`(anchor, requester)` rate limit tripped."
              },
              {
                "code": "INTERNAL_ERROR",
                "status": 500,
                "description": "ECIES encryption or operator signing failed."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_interop_fetchForRecipient",
              "resource_uri": "yf://interop/credential",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/interop.yaml#/InteropFetchForRecipientResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://pay.test.yieldfabric.com/graphql \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"mutation InteropFetchForRecipient($anchor: ChainAnchorInput!, $recipientPubkey: Hex!, $auth: AuthInput!) { interop_fetchForRecipient(anchor: $anchor, recipientPubkey: $recipientPubkey, auth: $auth) { anchor { tokenId } blob { ciphertext plaintextHash } } }\",\n    \"variables\": {\n      \"anchor\": { \"chainId\": 1, \"contractAddress\": \"0x0123...4567\", \"tokenId\": \"42\" },\n      \"recipientPubkey\": \"0x04abcd...\",\n      \"auth\": { \"claimedAddress\": \"0xa1b2...\", \"message\": \"...SIWE...\", \"signature\": \"0x...\" }\n    }\n  }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nquery = \"\"\"\nmutation InteropFetchForRecipient(\n  $anchor: ChainAnchorInput!\n  $recipientPubkey: Hex!\n  $auth: AuthInput!\n) {\n  interop_fetchForRecipient(\n    anchor: $anchor\n    recipientPubkey: $recipientPubkey\n    auth: $auth\n  ) {\n    anchor { chainId contractAddress tokenId }\n    blob { ciphertext plaintextHash serviceSignature serviceOperator schemaVersion exportedAt }\n  }\n}\n\"\"\"\nr = httpx.post(\n    \"https://pay.test.yieldfabric.com/graphql\",\n    json={\"query\": query, \"variables\": variables},\n)\nprint(r.json()[\"data\"][\"interop_fetchForRecipient\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://pay.test.yieldfabric.com/graphql\");\n\nconst FETCH_FOR_RECIPIENT = gql`\n  mutation InteropFetchForRecipient(\n    $anchor: ChainAnchorInput!\n    $recipientPubkey: Hex!\n    $auth: AuthInput!\n  ) {\n    interop_fetchForRecipient(\n      anchor: $anchor\n      recipientPubkey: $recipientPubkey\n      auth: $auth\n    ) {\n      anchor { chainId contractAddress tokenId }\n      blob { ciphertext plaintextHash }\n    }\n  }\n`;\n\nconst data = await client.request(FETCH_FOR_RECIPIENT, variables);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "mutation InteropFetchForRecipient(\n  $anchor: ChainAnchorInput!\n  $recipientPubkey: Hex!\n  $auth: AuthInput!\n) {\n  interop_fetchForRecipient(\n    anchor: $anchor\n    recipientPubkey: $recipientPubkey\n    auth: $auth\n  ) {\n    anchor { chainId contractAddress tokenId }\n    blob {\n      ciphertext\n      plaintextHash\n      serviceSignature\n      serviceOperator\n      schemaVersion\n      exportedAt\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "interop_exportCredentials",
                "relation": "alternative"
              },
              {
                "operation": "interop_importBundle",
                "relation": "alternative"
              },
              {
                "operation": "interop_listAnchors",
                "relation": "prev"
              },
              {
                "guide": "interop",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "payments",
            "kind": "query",
            "name": "payments",
            "service": "yieldfabric-payments",
            "tags": [
              "Queries"
            ],
            "summary": "List payments for the caller's entity",
            "description": "Returns every `Payment` visible to the authenticated caller's effective\nentity (`acting_as`-aware). Mirrors the per-entity dashboard view the\nfrontend renders; for filtered access by contract or wallet, use\n`payments.byContractId` / `payments.byWalletId` under the\n`paymentFlow.corePayments` sub-resolver.\n\n**Auth:** requires a valid JWT. No additional scope beyond\nauthentication.\n\n**Idempotency:** read-only.\n",
            "sdl": "query Payments {\n  payments {\n    id\n    amount\n    asset\n    payer { entity { id name } wallet { id address } }\n    payee { entity { id name } wallet { id address } }\n    status\n    createdAt\n  }\n}\n",
            "output": {
              "schema": {
                "type": "array",
                "description": "List of payments, ordered by createdAt DESC.",
                "items": {
                  "type": "object",
                  "required": [
                    "id",
                    "amount",
                    "balance",
                    "assetId",
                    "paymentType",
                    "status",
                    "dueDate",
                    "description",
                    "createdAt",
                    "deleted",
                    "transactionId",
                    "linearVesting",
                    "paymentCategory",
                    "isIndividuallyCancellable",
                    "canAccept",
                    "canCancel"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "amount": {
                      "type": "string",
                      "pattern": "^[0-9]+$",
                      "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                    },
                    "balance": {
                      "type": "string",
                      "pattern": "^[0-9]+$",
                      "description": "Unsigned 64-bit integer encoded as a decimal string. Used for token amounts\nand notionals where JavaScript's `Number` precision (53 bits) would lose\nsignificant digits.\n\n**Unit convention**: amounts are in the asset's native unit, NOT wei-scaled.\nExamples in this spec use values like `\"100\"` for \"100 USD\" or `\"5000\"` for\n\"5000 EUR\" — matching the convention in [yieldfabric-docs/05-PAYMENTS.md](../../../yieldfabric-docs/05-PAYMENTS.md)\nand the existing integration tests under `yieldfabric-payments/tests/`. The\non-chain settlement layer applies any necessary scaling internally.\n"
                    },
                    "assetId": {
                      "type": "string"
                    },
                    "paymentType": {
                      "type": "string",
                      "description": "GraphQL-specific payment type enum.",
                      "enum": [
                        "PAYABLE",
                        "RECEIVABLE",
                        "INTERNAL"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "PENDING",
                        "SCHEDULED",
                        "PROCESSING",
                        "COMPLETED",
                        "PAID",
                        "OVERDUE",
                        "FAILED",
                        "CANCELLED"
                      ]
                    },
                    "dueDate": {
                      "type": "string",
                      "format": "date-time",
                      "description": "ISO-8601 datetime (UTC)."
                    },
                    "description": {
                      "type": "string",
                      "description": "Federation: non-null for clean merging under `Position.asset`\nunion. Empty string when the underlying record has none.\n"
                    },
                    "contractId": {
                      "type": "string",
                      "nullable": true
                    },
                    "lockedInSwapId": {
                      "type": "string",
                      "nullable": true
                    },
                    "lockedInSwapStatus": {
                      "type": "string",
                      "nullable": true
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "ISO-8601 datetime (UTC)."
                    },
                    "deleted": {
                      "type": "boolean"
                    },
                    "transactionId": {
                      "type": "string"
                    },
                    "oracleAddressId": {
                      "type": "string",
                      "nullable": true
                    },
                    "oracleOwnerId": {
                      "type": "string",
                      "nullable": true
                    },
                    "oracleKeySender": {
                      "type": "string",
                      "nullable": true
                    },
                    "oracleValueSender": {
                      "type": "string",
                      "nullable": true
                    },
                    "oracleValueSenderSecret": {
                      "type": "string",
                      "nullable": true
                    },
                    "oracleKeyRecipient": {
                      "type": "string",
                      "nullable": true
                    },
                    "oracleValueRecipient": {
                      "type": "string",
                      "nullable": true
                    },
                    "oracleValueRecipientSecret": {
                      "type": "string",
                      "nullable": true
                    },
                    "unlockSender": {
                      "type": "string",
                      "format": "date-time",
                      "description": "ISO-8601 datetime (UTC)."
                    },
                    "unlockReceiver": {
                      "type": "string",
                      "format": "date-time",
                      "description": "ISO-8601 datetime (UTC)."
                    },
                    "linearVesting": {
                      "type": "boolean"
                    },
                    "obligorId": {
                      "type": "string",
                      "nullable": true
                    },
                    "paymentCategory": {
                      "type": "string",
                      "description": "Payment category classification — replaces name-based prefix checks.\n",
                      "enum": [
                        "REGULAR",
                        "SWAP",
                        "REPURCHASE",
                        "COLLATERAL"
                      ]
                    },
                    "isIndividuallyCancellable": {
                      "type": "boolean"
                    },
                    "canAccept": {
                      "type": "boolean",
                      "description": "Whether the current user can accept this payment."
                    },
                    "canCancel": {
                      "type": "boolean",
                      "description": "Whether the current user can cancel this payment."
                    }
                  }
                }
              }
            },
            "errors": [
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_payments",
              "resource_uri": "yf://payments",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/payments.yaml#/PaymentList"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{ \"query\": \"query Payments { payments { id amount asset status createdAt } }\" }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nresp = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"query Payments { payments { id amount asset status createdAt } }\",\n    },\n)\nprint(resp.json()[\"data\"][\"payments\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`query Payments {\n    payments {\n      id\n      amount\n      asset\n      status\n      createdAt\n    }\n  }`\n);\nconsole.log(data.payments);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "query Payments {\n  payments {\n    id\n    amount\n    asset\n    payer { entity { id name } wallet { id address } }\n    payee { entity { id name } wallet { id address } }\n    status\n    createdAt\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "contracts",
                "relation": "sibling"
              },
              {
                "operation": "swaps",
                "relation": "sibling"
              },
              {
                "operation": "positions",
                "relation": "sibling"
              }
            ]
          },
          {
            "operationId": "contracts",
            "kind": "query",
            "name": "contracts",
            "service": "yieldfabric-payments",
            "tags": [
              "Queries"
            ],
            "summary": "List contracts for the caller's entity",
            "description": "Returns every `Contract` visible to the authenticated caller's\neffective entity (`acting_as`-aware). Includes both flat obligations\nand composed-contract parents.\n\n- Only returns active contracts.\n- Contracts without payments are only included if the viewer is the\n  HOLDER.\n- For delegation JWTs: checks if the group (`acting_as`) is the holder.\n- For regular JWTs: checks if the user is the holder.\n- Includes all contracts in composed contracts that have active\n  payments.\n- Contracts locked in PENDING swaps are included but marked as locked.\n\n**Auth:** requires a valid JWT.\n\n**Idempotency:** read-only.\n",
            "sdl": "query Contracts {\n  contracts {\n    id\n    contractType\n    status\n    currency\n    expiryDate\n    parties {\n      role\n      entity { id }\n    }\n  }\n}\n",
            "output": {
              "schema": {
                "type": "array",
                "description": "List of contracts. Defined here for query convenience; the canonical\n`Contract` shape lives in `obligations.yaml`.\n",
                "items": {
                  "type": "object",
                  "required": [
                    "id",
                    "name",
                    "status",
                    "contractType",
                    "currency",
                    "startDate",
                    "expiryDate",
                    "createdAt"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string",
                      "nullable": true
                    },
                    "status": {
                      "type": "string",
                      "description": "Status of a contract.",
                      "enum": [
                        "DRAFT",
                        "PENDING",
                        "ACTIVE",
                        "COMPLETED",
                        "SUSPENDED",
                        "TERMINATED",
                        "EXPIRED",
                        "CANCELLED",
                        "OVERDUE"
                      ]
                    },
                    "contractType": {
                      "type": "string",
                      "description": "Types of contracts.",
                      "enum": [
                        "LOAN",
                        "INVOICE",
                        "FACTORING",
                        "LEASE",
                        "SERVICE",
                        "SUPPLY",
                        "OTHER"
                      ]
                    },
                    "currency": {
                      "type": "string"
                    },
                    "startDate": {
                      "type": "string",
                      "format": "date-time",
                      "description": "ISO-8601 datetime (UTC)."
                    },
                    "expiryDate": {
                      "type": "string",
                      "format": "date-time",
                      "description": "ISO-8601 datetime (UTC)."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "ISO-8601 datetime (UTC)."
                    },
                    "lockedInSwapId": {
                      "type": "string",
                      "nullable": true
                    },
                    "lockedInSwapStatus": {
                      "type": "string",
                      "nullable": true
                    },
                    "collateralInSwapId": {
                      "type": "string",
                      "nullable": true
                    },
                    "collateralInSwapStatus": {
                      "type": "string",
                      "nullable": true
                    },
                    "collateralSwapExpiry": {
                      "type": "string",
                      "format": "date-time",
                      "description": "ISO-8601 datetime (UTC)."
                    },
                    "tokenId": {
                      "type": "string",
                      "nullable": true
                    },
                    "composedContractId": {
                      "type": "string",
                      "nullable": true
                    }
                  }
                }
              }
            },
            "errors": [
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_contracts",
              "resource_uri": "yf://contracts",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/payments.yaml#/ContractList"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{ \"query\": \"query Contracts { contracts { id contractType status currency expiryDate parties { role entity { id } } } }\" }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nresp = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"query Contracts { contracts { id contractType status currency expiryDate parties { role entity { id } } } }\",\n    },\n)\nprint(resp.json()[\"data\"][\"contracts\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`query Contracts {\n    contracts {\n      id\n      contractType\n      status\n      currency\n      expiryDate\n      parties {\n        role\n        entity { id }\n      }\n    }\n  }`\n);\nconsole.log(data.contracts);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "query Contracts {\n  contracts {\n    id\n    contractType\n    status\n    currency\n    expiryDate\n    parties {\n      role\n      entity { id }\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "payments",
                "relation": "sibling"
              },
              {
                "operation": "swaps",
                "relation": "sibling"
              },
              {
                "operation": "positions",
                "relation": "sibling"
              }
            ]
          },
          {
            "operationId": "swaps",
            "kind": "query",
            "name": "swaps",
            "service": "yieldfabric-payments",
            "tags": [
              "Queries"
            ],
            "summary": "List swaps for the caller's entity",
            "description": "Returns swaps visible to the authenticated caller's effective entity.\nThis is a frontend-convenience field on the `swapFlow` sub-resolver\nthat wraps the core swap query.\n\nFor richer filtering (by id, by entity id, all) use\n`swapFlow.coreSwaps.byId` / `swapFlow.coreSwaps.byEntityId` /\n`swapFlow.coreSwaps.all`.\n\n**Auth:** requires a valid JWT.\n\n**Idempotency:** read-only.\n",
            "sdl": "query Swaps {\n  swapFlow {\n    swaps {\n      id\n      swapId\n      swapType\n      status\n      deadline\n      expiry\n      parties { entity { id name } wallet { id address } role }\n    }\n  }\n}\n",
            "output": {
              "schema": {
                "type": "array",
                "description": "List of swaps, ordered by createdAt DESC.",
                "items": {
                  "type": "object",
                  "required": [
                    "id",
                    "swapId",
                    "swapType",
                    "status",
                    "deadline",
                    "createdAt",
                    "deleted",
                    "transactionId",
                    "initiatorObligationIds",
                    "counterpartyObligationIds",
                    "paymentIds"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "swapId": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string",
                      "nullable": true,
                      "description": "Optional display name (e.g. \"Q4 2027 Repo\"). Exposed as `name` in GraphQL."
                    },
                    "swapType": {
                      "type": "string",
                      "description": "Types of swaps.",
                      "enum": [
                        "CONFIGURABLE"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "description": "Status of a swap.",
                      "enum": [
                        "PENDING",
                        "ACTIVE",
                        "COMPLETED",
                        "CANCELLED",
                        "EXPIRED",
                        "FORFEITED",
                        "REPURCHASED"
                      ]
                    },
                    "deadline": {
                      "type": "string",
                      "format": "date-time",
                      "description": "ISO-8601 datetime (UTC)."
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "ISO-8601 datetime (UTC)."
                    },
                    "deleted": {
                      "type": "boolean"
                    },
                    "transactionId": {
                      "type": "string"
                    },
                    "initiatorObligationIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "counterpartyObligationIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "paymentIds": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "initiatorExpectedPayments": {
                      "type": "string",
                      "nullable": true,
                      "description": "Resolve initiator expected payments as parsed JSON (string-encoded)."
                    },
                    "counterpartyExpectedPayments": {
                      "type": "string",
                      "nullable": true,
                      "description": "Resolve counterparty expected payments as parsed JSON (string-encoded)."
                    },
                    "expiry": {
                      "type": "string",
                      "format": "date-time",
                      "description": "ISO-8601 datetime (UTC)."
                    },
                    "initiatorCollateralObligationIds": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "type": "string"
                      }
                    },
                    "initiatorCollateralPayments": {
                      "type": "string",
                      "nullable": true,
                      "description": "Initiator collateral payments as JSON string."
                    },
                    "initiatorRepurchasePayments": {
                      "type": "string",
                      "nullable": true,
                      "description": "Initiator repurchase payments as JSON string."
                    },
                    "counterpartyCollateralObligationIds": {
                      "type": "array",
                      "nullable": true,
                      "items": {
                        "type": "string"
                      }
                    },
                    "counterpartyCollateralPayments": {
                      "type": "string",
                      "nullable": true,
                      "description": "Counterparty collateral payments as JSON string."
                    },
                    "counterpartyRepurchasePayments": {
                      "type": "string",
                      "nullable": true,
                      "description": "Counterparty repurchase payments as JSON string."
                    },
                    "sourceSwapId": {
                      "type": "string",
                      "nullable": true,
                      "description": "Source swap ID for swaps created via roll (lineage tracking)."
                    }
                  }
                }
              }
            },
            "errors": [
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_swaps",
              "resource_uri": "yf://swaps",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/swaps.yaml#/SwapList"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{ \"query\": \"query Swaps { swapFlow { swaps { id swapId status } } }\" }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nresp = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"query Swaps { swapFlow { swaps { id swapId swapType status deadline expiry } } }\",\n    },\n)\nprint(resp.json()[\"data\"][\"swapFlow\"][\"swaps\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`query Swaps {\n    swapFlow {\n      swaps {\n        id\n        swapId\n        swapType\n        status\n        deadline\n        expiry\n      }\n    }\n  }`\n);\nconsole.log(data.swapFlow.swaps);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "query Swaps {\n  swapFlow {\n    swaps {\n      id\n      swapId\n      swapType\n      status\n      deadline\n      expiry\n      parties { entity { id name } wallet { id address } role }\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "payments",
                "relation": "sibling"
              },
              {
                "operation": "contracts",
                "relation": "sibling"
              },
              {
                "operation": "positions",
                "relation": "sibling"
              }
            ]
          },
          {
            "operationId": "positions",
            "kind": "query",
            "name": "positions",
            "service": "yieldfabric-payments",
            "tags": [
              "Queries"
            ],
            "summary": "List positions for the caller's wallets",
            "description": "There is no top-level `positions` field on the root `Query`. Positions\nare a per-`Wallet` projection: walk `walletFlow.entityWallets` and\nselect each wallet's `positions`.\n\nPositions include both direct positions and those derived from contract\npayments, optimised with batch queries to avoid N+1. If positions are\npre-populated on the wallet they are returned directly.\n\n**Authorization:** users can see positions for wallets they own OR\nwallets of obligors they have exposure to.\n\n**Auth:** requires a valid JWT.\n\n**Idempotency:** read-only.\n",
            "sdl": "query Positions {\n  walletFlow {\n    entityWallets {\n      id\n      address\n      positions {\n        id\n        obligor { id }\n        asset\n        amount\n        status\n      }\n    }\n  }\n}\n",
            "output": {
              "schema": {
                "type": "array",
                "description": "Positions are exposed under `walletFlow.entityWallets.positions`. This wrapper\ncaptures the list-of-list-of-positions shape returned when querying across all\nof the caller's wallets. Each item is the array of positions for one wallet.\n",
                "items": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "additionalProperties": true
                  }
                }
              }
            },
            "errors": [
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_positions",
              "resource_uri": "yf://positions",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/payments.yaml#/PositionsByWalletList"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{ \"query\": \"query Positions { walletFlow { entityWallets { id positions { id asset amount status } } } }\" }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nresp = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"query Positions { walletFlow { entityWallets { id address positions { id asset amount status } } } }\",\n    },\n)\nprint(resp.json()[\"data\"][\"walletFlow\"][\"entityWallets\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`query Positions {\n    walletFlow {\n      entityWallets {\n        id\n        address\n        positions {\n          id\n          asset\n          amount\n          status\n        }\n      }\n    }\n  }`\n);\nconsole.log(data.walletFlow.entityWallets);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "query Positions {\n  walletFlow {\n    entityWallets {\n      id\n      address\n      positions {\n        id\n        obligor { id }\n        asset\n        amount\n        status\n      }\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "payments",
                "relation": "sibling"
              },
              {
                "operation": "contracts",
                "relation": "sibling"
              },
              {
                "operation": "swaps",
                "relation": "sibling"
              }
            ]
          },
          {
            "operationId": "entities",
            "kind": "query",
            "name": "entities",
            "service": "yieldfabric-payments",
            "tags": [
              "Queries"
            ],
            "summary": "Entity directory queries",
            "description": "Root `entities(queryType: String): EntityQuery!` namespaces directory\nqueries. Use the returned `EntityQuery` to walk to:\n\n- `byId(id: String!): Entity`\n- `history(id: String!): [Entity!]!`\n- `asOf(id: String!, timestamp: DateTime!): Entity`\n- `all(queryType: String): [Entity!]!`\n- `allAsOf(timestamp: DateTime!): [Entity!]!`\n\n**Federation:** the `entities` field is `@shareable`. Both `auth` and\n`payments` declare it; the gateway picks one resolver per request.\n`auth`'s resolver is direct DB; `payments` delegates via\n`IdentityReader → auth` (extra hop). Same result either way.\n\n**Auth:** requires a valid JWT.\n\n**Idempotency:** read-only.\n",
            "sdl": "query Entities($queryType: String, $id: String!) {\n  entities(queryType: $queryType) {\n    byId(id: $id) {\n      id\n      name\n      entityType\n      status\n    }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "properties": {
                  "queryType": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Optional filter for the entity query sub-resolver. Accepted values\ncome from the EntityQuery sub-resolver; consult the live SDL.\n"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Fetch a single entity by id",
                  "value": {
                    "queryType": null,
                    "id": "user_alice_123"
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "description": "Marker type for the `entities(queryType: String): EntityQuery!` sub-resolver.\nActual entity data is fetched via further selection (`entities { byId(...) }`).\nTreated as opaque here; clients should construct nested selections rather than\nconsume this type wholesale.\n",
                "additionalProperties": true
              }
            },
            "errors": [
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_entities",
              "resource_uri": "yf://entities",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/payments.yaml#/EntityQueryResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"query Entities($id: String!) { entities { byId(id: $id) { id name entityType status } } }\",\n    \"variables\": { \"id\": \"user_alice_123\" }\n  }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nresp = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"query Entities($id: String!) { entities { byId(id: $id) { id name entityType status } } }\",\n        \"variables\": {\"id\": \"user_alice_123\"},\n    },\n)\nprint(resp.json()[\"data\"][\"entities\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`query Entities($id: String!) {\n    entities {\n      byId(id: $id) {\n        id\n        name\n        entityType\n        status\n      }\n    }\n  }`,\n  { id: \"user_alice_123\" }\n);\nconsole.log(data.entities);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "query Entities($queryType: String, $id: String!) {\n  entities(queryType: $queryType) {\n    byId(id: $id) {\n      id\n      name\n      entityType\n      status\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "payments",
                "relation": "sibling"
              },
              {
                "operation": "contracts",
                "relation": "sibling"
              }
            ]
          },
          {
            "operationId": "dealById",
            "kind": "query",
            "name": "dealById",
            "service": "yieldfabric-dms",
            "tags": [
              "Queries"
            ],
            "summary": "Fetch a single deal by id",
            "description": "Top-level fetch of a single deal by ID. Parallel of the federation\n`find_deal_by_id` entity resolver; this one is reachable directly from\na client (no `_entities` round-trip needed).\n\n**Authorization:** caller must be either party of the deal. The\nfederation entity resolver is intentionally open (entity-reference\nstitching needs to resolve any id any subgraph hands it), but the\nsurfacing path consumed by the front-end deal-detail page enforces\nparty-membership so non-parties can't enumerate deal contents (plan,\nsignatures, capabilities) by guessing IDs.\n\n**Auth:** requires a valid JWT plus party-membership on the deal.\n\n**Idempotency:** read-only.\n",
            "sdl": "query DealById($id: String!) {\n  dealFlow {\n    dealById(id: $id) {\n      id\n      status\n      name\n      proposer { id name }\n      parties { entityId role }\n      signatures { partyEntityId role signedAt }\n      plan\n      cashflowRef\n      createdAt\n      acceptedAt\n      activatedAt\n      workflowId\n    }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "id"
                ],
                "properties": {
                  "id": {
                    "type": "string",
                    "description": "Deal id (e.g. DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f)."
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Fetch a deal by id",
                  "value": {
                    "id": "DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f"
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "object",
                "required": [
                  "id",
                  "kind",
                  "status",
                  "planHash",
                  "plan",
                  "proposerEntityId",
                  "parties",
                  "versionAt",
                  "deleted",
                  "transactionId",
                  "signatures",
                  "events",
                  "capabilities"
                ],
                "properties": {
                  "id": {
                    "type": "string"
                  },
                  "kind": {
                    "type": "string",
                    "description": "Whether this row is a fully-fledged signed deal between two parties or\nan internal orchestration template.\n",
                    "enum": [
                      "SIGNED_DEAL",
                      "ORCHESTRATION"
                    ]
                  },
                  "name": {
                    "type": "string",
                    "nullable": true,
                    "description": "User-supplied label captured at `proposeDeal`. `None` when the\ncaller didn't supply one (orchestration-kind deals are always\n`None` — they're programmatically materialised, not user-named).\n"
                  },
                  "status": {
                    "type": "string",
                    "description": "Lifecycle status of a deal. Maps 1:1 to `data::types::deals::DealStatus`.\n",
                    "enum": [
                      "DRAFT",
                      "PROPOSED",
                      "ACCEPTED",
                      "COUNTER_OFFERED",
                      "REJECTED",
                      "ACTIVE",
                      "COMPLETED",
                      "CANCELLED",
                      "DEFAULTED",
                      "FAILED_AFTER_PARTIAL_EXECUTION"
                    ]
                  },
                  "planHash": {
                    "type": "string"
                  },
                  "plan": {
                    "description": "Arbitrary JSON value (object, array, scalar, or null)."
                  },
                  "proposerEntityId": {
                    "type": "string",
                    "description": "Proposer entity ID. Phase 2g will replace this with `proposer: Entity!`\nstitched from the auth subgraph; v1 exposes the raw ID string.\n"
                  },
                  "parties": {
                    "type": "array",
                    "description": "Counter-signing principals on this deal, in plan-authored order.\nEmpty list for orchestration-kind deals.\n",
                    "items": {
                      "type": "object",
                      "description": "One counter-signing principal on a deal. Returned as part of a Deal's\n`parties` field. The `role` is the user-authored IRI used in the plan\n(e.g. `\"counterparty\"`, `\"lender\"`, `\"borrower\"`, `\"custodian\"`).\n",
                      "required": [
                        "entityId",
                        "role"
                      ],
                      "properties": {
                        "entityId": {
                          "type": "string"
                        },
                        "role": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "parentDealId": {
                    "type": "string",
                    "nullable": true
                  },
                  "cashflowRef": {
                    "type": "string",
                    "nullable": true
                  },
                  "workflowId": {
                    "type": "string",
                    "nullable": true
                  },
                  "versionAt": {
                    "type": "string",
                    "format": "date-time",
                    "description": "ISO-8601 datetime (UTC)."
                  },
                  "acceptedAt": {
                    "type": "string",
                    "format": "date-time",
                    "description": "ISO-8601 datetime (UTC)."
                  },
                  "completedAt": {
                    "type": "string",
                    "format": "date-time",
                    "description": "ISO-8601 datetime (UTC)."
                  },
                  "cancelledAt": {
                    "type": "string",
                    "format": "date-time",
                    "description": "ISO-8601 datetime (UTC)."
                  },
                  "deleted": {
                    "type": "boolean"
                  },
                  "transactionId": {
                    "type": "string"
                  },
                  "signatures": {
                    "type": "array",
                    "description": "Signatures attached to this deal, ordered by `signed_at` ASC.\nEmpty list for `Orchestration` deals (no signatures expected).\nRequires `Arc<DealStore>` registered in the schema's context.\n",
                    "items": {
                      "type": "object",
                      "description": "One signature on a deal. Returned as part of a Deal's `signatures` field.\n",
                      "required": [
                        "dealId",
                        "role",
                        "partyEntityId",
                        "sigPayload",
                        "signedAt"
                      ],
                      "properties": {
                        "dealId": {
                          "type": "string"
                        },
                        "role": {
                          "type": "string"
                        },
                        "partyEntityId": {
                          "type": "string"
                        },
                        "sigPayload": {
                          "description": "Arbitrary JSON value (object, array, scalar, or null)."
                        },
                        "signedAt": {
                          "type": "string",
                          "format": "date-time",
                          "description": "ISO-8601 datetime (UTC)."
                        }
                      }
                    }
                  },
                  "events": {
                    "type": "array",
                    "description": "Audit-log events for this deal, ordered by `sequence` ASC.\nSequences are monotonic-but-not-dense within a deal.\n",
                    "items": {
                      "type": "object",
                      "description": "One audit-log entry for a deal.",
                      "required": [
                        "dealId",
                        "sequence",
                        "eventType",
                        "payload",
                        "occurredAt"
                      ],
                      "properties": {
                        "dealId": {
                          "type": "string"
                        },
                        "sequence": {
                          "type": "integer",
                          "description": "Monotonic-but-not-dense within a deal (BIGSERIAL is global)."
                        },
                        "eventType": {
                          "type": "string"
                        },
                        "actorEntityId": {
                          "type": "string",
                          "nullable": true,
                          "description": "`None` for system-emitted events (timer firings, scheduler ticks)."
                        },
                        "payload": {
                          "description": "Arbitrary JSON value (object, array, scalar, or null)."
                        },
                        "occurredAt": {
                          "type": "string",
                          "format": "date-time",
                          "description": "ISO-8601 datetime (UTC)."
                        }
                      }
                    }
                  },
                  "capabilities": {
                    "type": "array",
                    "description": "Active (non-revoked) delegation capabilities for this deal.\nRevoked capabilities are filtered out — callers wanting full\nhistory should query a future `capabilityHistory` endpoint.\n",
                    "items": {
                      "type": "object",
                      "required": [
                        "id",
                        "dealId",
                        "grantedByEntityId",
                        "capabilityKind",
                        "allowedDescriptors",
                        "allowedParamConstraints",
                        "planHashBinding",
                        "grantedAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "dealId": {
                          "type": "string"
                        },
                        "grantedByEntityId": {
                          "type": "string"
                        },
                        "capabilityKind": {
                          "type": "string"
                        },
                        "walletId": {
                          "type": "string",
                          "nullable": true
                        },
                        "accountAddress": {
                          "type": "string",
                          "nullable": true
                        },
                        "allowedDescriptors": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "allowedParamConstraints": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "description": "One parameter constraint on a capability. Exposed as a typed GraphQL\ntype rather than opaque JSON so clients can render constraints in the\nUI without parsing.\n",
                            "required": [
                              "descriptor",
                              "field",
                              "kind"
                            ],
                            "properties": {
                              "descriptor": {
                                "type": "string"
                              },
                              "field": {
                                "type": "string"
                              },
                              "kind": {
                                "description": "Constraint variants. Modeled as a GraphQL union of variant-specific\npayload types so clients can dispatch on `__typename`.\n",
                                "oneOf": [
                                  {
                                    "type": "object",
                                    "required": [
                                      "value"
                                    ],
                                    "properties": {
                                      "value": {
                                        "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                      }
                                    }
                                  },
                                  {
                                    "type": "object",
                                    "required": [
                                      "values"
                                    ],
                                    "properties": {
                                      "values": {
                                        "type": "array",
                                        "items": {
                                          "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                        }
                                      }
                                    }
                                  },
                                  {
                                    "type": "object",
                                    "required": [
                                      "value"
                                    ],
                                    "properties": {
                                      "value": {
                                        "type": "string"
                                      }
                                    }
                                  },
                                  {
                                    "type": "object",
                                    "required": [
                                      "value"
                                    ],
                                    "properties": {
                                      "value": {
                                        "type": "string"
                                      }
                                    }
                                  }
                                ]
                              }
                            }
                          }
                        },
                        "planHashBinding": {
                          "type": "string"
                        },
                        "grantedAt": {
                          "type": "string",
                          "format": "date-time",
                          "description": "ISO-8601 datetime (UTC)."
                        },
                        "revokedAt": {
                          "type": "string",
                          "format": "date-time",
                          "description": "ISO-8601 datetime (UTC)."
                        }
                      }
                    }
                  }
                }
              }
            },
            "errors": [
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "FORBIDDEN",
                "status": 403,
                "description": "Caller is not a party on this deal."
              },
              {
                "code": "NOT_FOUND",
                "status": 404,
                "description": "No deal with the given `id`."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_dealById",
              "resource_uri": "yf://deals",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/deals.yaml#/DealByIdResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"query DealById($id: String!) { dealFlow { dealById(id: $id) { id status name } } }\",\n    \"variables\": { \"id\": \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\" }\n  }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nresp = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"query DealById($id: String!) { dealFlow { dealById(id: $id) { id status name proposer { id name } parties { entityId role } createdAt } } }\",\n        \"variables\": {\"id\": \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\"},\n    },\n)\nprint(resp.json()[\"data\"][\"dealFlow\"][\"dealById\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`query DealById($id: String!) {\n    dealFlow {\n      dealById(id: $id) {\n        id\n        status\n        name\n        proposer { id name }\n        parties { entityId role }\n        signatures { partyEntityId role signedAt }\n        createdAt\n        activatedAt\n      }\n    }\n  }`,\n  { id: \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\" }\n);\nconsole.log(data.dealFlow.dealById);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "query DealById($id: String!) {\n  dealFlow {\n    dealById(id: $id) {\n      id\n      status\n      name\n      proposer { id name }\n      parties { entityId role }\n      signatures { partyEntityId role signedAt }\n      plan\n      cashflowRef\n      createdAt\n      acceptedAt\n      activatedAt\n      workflowId\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "dealsByParty",
                "relation": "sibling"
              },
              {
                "operation": "dealAgreement",
                "relation": "sibling"
              },
              {
                "operation": "proposeDeal",
                "relation": "alternative"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "dealsByParty",
            "kind": "query",
            "name": "dealsByParty",
            "service": "yieldfabric-dms",
            "tags": [
              "Queries"
            ],
            "summary": "List deals where the caller is a party",
            "description": "List deals where the caller is `proposer` / `counterparty` / `either`\nparty. Optional `status` narrows the result. Always filtered to\nnon-deleted; ordered by deal id (the underlying store helper's\ndeterministic order).\n\n**Auth:** requires a valid JWT.\n\n**Idempotency:** read-only.\n",
            "sdl": "query DealsByParty($role: PartyRoleFilter, $status: DealStatus) {\n  dealFlow {\n    dealsByParty(role: $role, status: $status) {\n      id\n      status\n      name\n      parties { entityId role }\n      createdAt\n    }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "properties": {
                  "role": {
                    "type": "string",
                    "enum": [
                      "PROPOSER",
                      "COUNTERPARTY",
                      "EITHER"
                    ],
                    "description": "Filter for `dealsByParty`. PROPOSER → deals where the caller is\n`proposer_entity_id`. COUNTERPARTY → deals where the caller is listed in\n`Deal.parties` (any role). EITHER → both.\n"
                  },
                  "status": {
                    "type": "string",
                    "description": "Lifecycle status of a deal. Maps 1:1 to `data::types::deals::DealStatus`.\n",
                    "enum": [
                      "DRAFT",
                      "PROPOSED",
                      "ACCEPTED",
                      "COUNTER_OFFERED",
                      "REJECTED",
                      "ACTIVE",
                      "COMPLETED",
                      "CANCELLED",
                      "DEFAULTED",
                      "FAILED_AFTER_PARTIAL_EXECUTION"
                    ]
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "All proposed deals where I'm a party",
                  "value": {
                    "role": "either",
                    "status": "PROPOSED"
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "id",
                    "kind",
                    "status",
                    "planHash",
                    "plan",
                    "proposerEntityId",
                    "parties",
                    "versionAt",
                    "deleted",
                    "transactionId",
                    "signatures",
                    "events",
                    "capabilities"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "kind": {
                      "type": "string",
                      "description": "Whether this row is a fully-fledged signed deal between two parties or\nan internal orchestration template.\n",
                      "enum": [
                        "SIGNED_DEAL",
                        "ORCHESTRATION"
                      ]
                    },
                    "name": {
                      "type": "string",
                      "nullable": true,
                      "description": "User-supplied label captured at `proposeDeal`. `None` when the\ncaller didn't supply one (orchestration-kind deals are always\n`None` — they're programmatically materialised, not user-named).\n"
                    },
                    "status": {
                      "type": "string",
                      "description": "Lifecycle status of a deal. Maps 1:1 to `data::types::deals::DealStatus`.\n",
                      "enum": [
                        "DRAFT",
                        "PROPOSED",
                        "ACCEPTED",
                        "COUNTER_OFFERED",
                        "REJECTED",
                        "ACTIVE",
                        "COMPLETED",
                        "CANCELLED",
                        "DEFAULTED",
                        "FAILED_AFTER_PARTIAL_EXECUTION"
                      ]
                    },
                    "planHash": {
                      "type": "string"
                    },
                    "plan": {
                      "description": "Arbitrary JSON value (object, array, scalar, or null)."
                    },
                    "proposerEntityId": {
                      "type": "string",
                      "description": "Proposer entity ID. Phase 2g will replace this with `proposer: Entity!`\nstitched from the auth subgraph; v1 exposes the raw ID string.\n"
                    },
                    "parties": {
                      "type": "array",
                      "description": "Counter-signing principals on this deal, in plan-authored order.\nEmpty list for orchestration-kind deals.\n",
                      "items": {
                        "type": "object",
                        "description": "One counter-signing principal on a deal. Returned as part of a Deal's\n`parties` field. The `role` is the user-authored IRI used in the plan\n(e.g. `\"counterparty\"`, `\"lender\"`, `\"borrower\"`, `\"custodian\"`).\n",
                        "required": [
                          "entityId",
                          "role"
                        ],
                        "properties": {
                          "entityId": {
                            "type": "string"
                          },
                          "role": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "parentDealId": {
                      "type": "string",
                      "nullable": true
                    },
                    "cashflowRef": {
                      "type": "string",
                      "nullable": true
                    },
                    "workflowId": {
                      "type": "string",
                      "nullable": true
                    },
                    "versionAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "ISO-8601 datetime (UTC)."
                    },
                    "acceptedAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "ISO-8601 datetime (UTC)."
                    },
                    "completedAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "ISO-8601 datetime (UTC)."
                    },
                    "cancelledAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "ISO-8601 datetime (UTC)."
                    },
                    "deleted": {
                      "type": "boolean"
                    },
                    "transactionId": {
                      "type": "string"
                    },
                    "signatures": {
                      "type": "array",
                      "description": "Signatures attached to this deal, ordered by `signed_at` ASC.\nEmpty list for `Orchestration` deals (no signatures expected).\nRequires `Arc<DealStore>` registered in the schema's context.\n",
                      "items": {
                        "type": "object",
                        "description": "One signature on a deal. Returned as part of a Deal's `signatures` field.\n",
                        "required": [
                          "dealId",
                          "role",
                          "partyEntityId",
                          "sigPayload",
                          "signedAt"
                        ],
                        "properties": {
                          "dealId": {
                            "type": "string"
                          },
                          "role": {
                            "type": "string"
                          },
                          "partyEntityId": {
                            "type": "string"
                          },
                          "sigPayload": {
                            "description": "Arbitrary JSON value (object, array, scalar, or null)."
                          },
                          "signedAt": {
                            "type": "string",
                            "format": "date-time",
                            "description": "ISO-8601 datetime (UTC)."
                          }
                        }
                      }
                    },
                    "events": {
                      "type": "array",
                      "description": "Audit-log events for this deal, ordered by `sequence` ASC.\nSequences are monotonic-but-not-dense within a deal.\n",
                      "items": {
                        "type": "object",
                        "description": "One audit-log entry for a deal.",
                        "required": [
                          "dealId",
                          "sequence",
                          "eventType",
                          "payload",
                          "occurredAt"
                        ],
                        "properties": {
                          "dealId": {
                            "type": "string"
                          },
                          "sequence": {
                            "type": "integer",
                            "description": "Monotonic-but-not-dense within a deal (BIGSERIAL is global)."
                          },
                          "eventType": {
                            "type": "string"
                          },
                          "actorEntityId": {
                            "type": "string",
                            "nullable": true,
                            "description": "`None` for system-emitted events (timer firings, scheduler ticks)."
                          },
                          "payload": {
                            "description": "Arbitrary JSON value (object, array, scalar, or null)."
                          },
                          "occurredAt": {
                            "type": "string",
                            "format": "date-time",
                            "description": "ISO-8601 datetime (UTC)."
                          }
                        }
                      }
                    },
                    "capabilities": {
                      "type": "array",
                      "description": "Active (non-revoked) delegation capabilities for this deal.\nRevoked capabilities are filtered out — callers wanting full\nhistory should query a future `capabilityHistory` endpoint.\n",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "dealId",
                          "grantedByEntityId",
                          "capabilityKind",
                          "allowedDescriptors",
                          "allowedParamConstraints",
                          "planHashBinding",
                          "grantedAt"
                        ],
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "dealId": {
                            "type": "string"
                          },
                          "grantedByEntityId": {
                            "type": "string"
                          },
                          "capabilityKind": {
                            "type": "string"
                          },
                          "walletId": {
                            "type": "string",
                            "nullable": true
                          },
                          "accountAddress": {
                            "type": "string",
                            "nullable": true
                          },
                          "allowedDescriptors": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "allowedParamConstraints": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "description": "One parameter constraint on a capability. Exposed as a typed GraphQL\ntype rather than opaque JSON so clients can render constraints in the\nUI without parsing.\n",
                              "required": [
                                "descriptor",
                                "field",
                                "kind"
                              ],
                              "properties": {
                                "descriptor": {
                                  "type": "string"
                                },
                                "field": {
                                  "type": "string"
                                },
                                "kind": {
                                  "description": "Constraint variants. Modeled as a GraphQL union of variant-specific\npayload types so clients can dispatch on `__typename`.\n",
                                  "oneOf": [
                                    {
                                      "type": "object",
                                      "required": [
                                        "value"
                                      ],
                                      "properties": {
                                        "value": {
                                          "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                        }
                                      }
                                    },
                                    {
                                      "type": "object",
                                      "required": [
                                        "values"
                                      ],
                                      "properties": {
                                        "values": {
                                          "type": "array",
                                          "items": {
                                            "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                          }
                                        }
                                      }
                                    },
                                    {
                                      "type": "object",
                                      "required": [
                                        "value"
                                      ],
                                      "properties": {
                                        "value": {
                                          "type": "string"
                                        }
                                      }
                                    },
                                    {
                                      "type": "object",
                                      "required": [
                                        "value"
                                      ],
                                      "properties": {
                                        "value": {
                                          "type": "string"
                                        }
                                      }
                                    }
                                  ]
                                }
                              }
                            }
                          },
                          "planHashBinding": {
                            "type": "string"
                          },
                          "grantedAt": {
                            "type": "string",
                            "format": "date-time",
                            "description": "ISO-8601 datetime (UTC)."
                          },
                          "revokedAt": {
                            "type": "string",
                            "format": "date-time",
                            "description": "ISO-8601 datetime (UTC)."
                          }
                        }
                      }
                    }
                  }
                }
              }
            },
            "errors": [
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_dealsByParty",
              "resource_uri": "yf://deals",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/deals.yaml#/DealsByPartyResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"query DealsByParty($role: PartyRoleFilter, $status: DealStatus) { dealFlow { dealsByParty(role: $role, status: $status) { id status name } } }\",\n    \"variables\": { \"role\": \"either\", \"status\": \"PROPOSED\" }\n  }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nresp = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"query DealsByParty($role: PartyRoleFilter, $status: DealStatus) { dealFlow { dealsByParty(role: $role, status: $status) { id status name parties { entityId role } createdAt } } }\",\n        \"variables\": {\"role\": \"either\", \"status\": \"PROPOSED\"},\n    },\n)\nprint(resp.json()[\"data\"][\"dealFlow\"][\"dealsByParty\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`query DealsByParty($role: PartyRoleFilter, $status: DealStatus) {\n    dealFlow {\n      dealsByParty(role: $role, status: $status) {\n        id\n        status\n        name\n        parties { entityId role }\n        createdAt\n      }\n    }\n  }`,\n  { role: \"either\", status: \"PROPOSED\" }\n);\nconsole.log(data.dealFlow.dealsByParty);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "query DealsByParty($role: PartyRoleFilter, $status: DealStatus) {\n  dealFlow {\n    dealsByParty(role: $role, status: $status) {\n      id\n      status\n      name\n      parties { entityId role }\n      createdAt\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "dealById",
                "relation": "sibling"
              },
              {
                "operation": "dealsAwaitingMySignature",
                "relation": "sibling"
              },
              {
                "operation": "myInbox",
                "relation": "sibling"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "dealsAwaitingMySignature",
            "kind": "query",
            "name": "dealsAwaitingMySignature",
            "service": "yieldfabric-dms",
            "tags": [
              "Queries"
            ],
            "summary": "List proposed deals awaiting the caller's signature",
            "description": "`Proposed` deals where the caller is listed in `Deal.parties` and\nhasn't yet signed. Drives the front-end's \"Awaiting my signature\" tab\nand the deal-arm of `myInbox`.\n\n**Auth:** requires a valid JWT.\n\n**Idempotency:** read-only.\n",
            "sdl": "query DealsAwaitingMySignature {\n  dealFlow {\n    dealsAwaitingMySignature {\n      id\n      status\n      name\n      proposer { id name }\n      parties { entityId role }\n      createdAt\n    }\n  }\n}\n",
            "output": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "object",
                  "description": "A deal waiting on the caller's signature. Wraps Deal in a distinct\nGraphQL type so the `InboxItem` union can discriminate.\n",
                  "properties": {
                    "deal": {
                      "type": "object",
                      "required": [
                        "id",
                        "kind",
                        "status",
                        "planHash",
                        "plan",
                        "proposerEntityId",
                        "parties",
                        "versionAt",
                        "deleted",
                        "transactionId",
                        "signatures",
                        "events",
                        "capabilities"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "kind": {
                          "type": "string",
                          "description": "Whether this row is a fully-fledged signed deal between two parties or\nan internal orchestration template.\n",
                          "enum": [
                            "SIGNED_DEAL",
                            "ORCHESTRATION"
                          ]
                        },
                        "name": {
                          "type": "string",
                          "nullable": true,
                          "description": "User-supplied label captured at `proposeDeal`. `None` when the\ncaller didn't supply one (orchestration-kind deals are always\n`None` — they're programmatically materialised, not user-named).\n"
                        },
                        "status": {
                          "type": "string",
                          "description": "Lifecycle status of a deal. Maps 1:1 to `data::types::deals::DealStatus`.\n",
                          "enum": [
                            "DRAFT",
                            "PROPOSED",
                            "ACCEPTED",
                            "COUNTER_OFFERED",
                            "REJECTED",
                            "ACTIVE",
                            "COMPLETED",
                            "CANCELLED",
                            "DEFAULTED",
                            "FAILED_AFTER_PARTIAL_EXECUTION"
                          ]
                        },
                        "planHash": {
                          "type": "string"
                        },
                        "plan": {
                          "description": "Arbitrary JSON value (object, array, scalar, or null)."
                        },
                        "proposerEntityId": {
                          "type": "string",
                          "description": "Proposer entity ID. Phase 2g will replace this with `proposer: Entity!`\nstitched from the auth subgraph; v1 exposes the raw ID string.\n"
                        },
                        "parties": {
                          "type": "array",
                          "description": "Counter-signing principals on this deal, in plan-authored order.\nEmpty list for orchestration-kind deals.\n",
                          "items": {
                            "type": "object",
                            "description": "One counter-signing principal on a deal. Returned as part of a Deal's\n`parties` field. The `role` is the user-authored IRI used in the plan\n(e.g. `\"counterparty\"`, `\"lender\"`, `\"borrower\"`, `\"custodian\"`).\n",
                            "required": [
                              "entityId",
                              "role"
                            ],
                            "properties": {
                              "entityId": {
                                "type": "string"
                              },
                              "role": {
                                "type": "string"
                              }
                            }
                          }
                        },
                        "parentDealId": {
                          "type": "string",
                          "nullable": true
                        },
                        "cashflowRef": {
                          "type": "string",
                          "nullable": true
                        },
                        "workflowId": {
                          "type": "string",
                          "nullable": true
                        },
                        "versionAt": {
                          "type": "string",
                          "format": "date-time",
                          "description": "ISO-8601 datetime (UTC)."
                        },
                        "acceptedAt": {
                          "type": "string",
                          "format": "date-time",
                          "description": "ISO-8601 datetime (UTC)."
                        },
                        "completedAt": {
                          "type": "string",
                          "format": "date-time",
                          "description": "ISO-8601 datetime (UTC)."
                        },
                        "cancelledAt": {
                          "type": "string",
                          "format": "date-time",
                          "description": "ISO-8601 datetime (UTC)."
                        },
                        "deleted": {
                          "type": "boolean"
                        },
                        "transactionId": {
                          "type": "string"
                        },
                        "signatures": {
                          "type": "array",
                          "description": "Signatures attached to this deal, ordered by `signed_at` ASC.\nEmpty list for `Orchestration` deals (no signatures expected).\nRequires `Arc<DealStore>` registered in the schema's context.\n",
                          "items": {
                            "type": "object",
                            "description": "One signature on a deal. Returned as part of a Deal's `signatures` field.\n",
                            "required": [
                              "dealId",
                              "role",
                              "partyEntityId",
                              "sigPayload",
                              "signedAt"
                            ],
                            "properties": {
                              "dealId": {
                                "type": "string"
                              },
                              "role": {
                                "type": "string"
                              },
                              "partyEntityId": {
                                "type": "string"
                              },
                              "sigPayload": {
                                "description": "Arbitrary JSON value (object, array, scalar, or null)."
                              },
                              "signedAt": {
                                "type": "string",
                                "format": "date-time",
                                "description": "ISO-8601 datetime (UTC)."
                              }
                            }
                          }
                        },
                        "events": {
                          "type": "array",
                          "description": "Audit-log events for this deal, ordered by `sequence` ASC.\nSequences are monotonic-but-not-dense within a deal.\n",
                          "items": {
                            "type": "object",
                            "description": "One audit-log entry for a deal.",
                            "required": [
                              "dealId",
                              "sequence",
                              "eventType",
                              "payload",
                              "occurredAt"
                            ],
                            "properties": {
                              "dealId": {
                                "type": "string"
                              },
                              "sequence": {
                                "type": "integer",
                                "description": "Monotonic-but-not-dense within a deal (BIGSERIAL is global)."
                              },
                              "eventType": {
                                "type": "string"
                              },
                              "actorEntityId": {
                                "type": "string",
                                "nullable": true,
                                "description": "`None` for system-emitted events (timer firings, scheduler ticks)."
                              },
                              "payload": {
                                "description": "Arbitrary JSON value (object, array, scalar, or null)."
                              },
                              "occurredAt": {
                                "type": "string",
                                "format": "date-time",
                                "description": "ISO-8601 datetime (UTC)."
                              }
                            }
                          }
                        },
                        "capabilities": {
                          "type": "array",
                          "description": "Active (non-revoked) delegation capabilities for this deal.\nRevoked capabilities are filtered out — callers wanting full\nhistory should query a future `capabilityHistory` endpoint.\n",
                          "items": {
                            "type": "object",
                            "required": [
                              "id",
                              "dealId",
                              "grantedByEntityId",
                              "capabilityKind",
                              "allowedDescriptors",
                              "allowedParamConstraints",
                              "planHashBinding",
                              "grantedAt"
                            ],
                            "properties": {
                              "id": {
                                "type": "string"
                              },
                              "dealId": {
                                "type": "string"
                              },
                              "grantedByEntityId": {
                                "type": "string"
                              },
                              "capabilityKind": {
                                "type": "string"
                              },
                              "walletId": {
                                "type": "string",
                                "nullable": true
                              },
                              "accountAddress": {
                                "type": "string",
                                "nullable": true
                              },
                              "allowedDescriptors": {
                                "type": "array",
                                "items": {
                                  "type": "string"
                                }
                              },
                              "allowedParamConstraints": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "description": "One parameter constraint on a capability. Exposed as a typed GraphQL\ntype rather than opaque JSON so clients can render constraints in the\nUI without parsing.\n",
                                  "required": [
                                    "descriptor",
                                    "field",
                                    "kind"
                                  ],
                                  "properties": {
                                    "descriptor": {
                                      "type": "string"
                                    },
                                    "field": {
                                      "type": "string"
                                    },
                                    "kind": {
                                      "description": "Constraint variants. Modeled as a GraphQL union of variant-specific\npayload types so clients can dispatch on `__typename`.\n",
                                      "oneOf": [
                                        {
                                          "type": "object",
                                          "required": [
                                            "value"
                                          ],
                                          "properties": {
                                            "value": {
                                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                            }
                                          }
                                        },
                                        {
                                          "type": "object",
                                          "required": [
                                            "values"
                                          ],
                                          "properties": {
                                            "values": {
                                              "type": "array",
                                              "items": {
                                                "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                              }
                                            }
                                          }
                                        },
                                        {
                                          "type": "object",
                                          "required": [
                                            "value"
                                          ],
                                          "properties": {
                                            "value": {
                                              "type": "string"
                                            }
                                          }
                                        },
                                        {
                                          "type": "object",
                                          "required": [
                                            "value"
                                          ],
                                          "properties": {
                                            "value": {
                                              "type": "string"
                                            }
                                          }
                                        }
                                      ]
                                    }
                                  }
                                }
                              },
                              "planHashBinding": {
                                "type": "string"
                              },
                              "grantedAt": {
                                "type": "string",
                                "format": "date-time",
                                "description": "ISO-8601 datetime (UTC)."
                              },
                              "revokedAt": {
                                "type": "string",
                                "format": "date-time",
                                "description": "ISO-8601 datetime (UTC)."
                              }
                            }
                          }
                        }
                      }
                    }
                  }
                }
              }
            },
            "errors": [
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_dealsAwaitingMySignature",
              "resource_uri": "yf://deals",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/deals.yaml#/DealsAwaitingMySignatureResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{ \"query\": \"query DealsAwaitingMySignature { dealFlow { dealsAwaitingMySignature { id status name } } }\" }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nresp = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"query DealsAwaitingMySignature { dealFlow { dealsAwaitingMySignature { id status name proposer { id name } parties { entityId role } createdAt } } }\",\n    },\n)\nprint(resp.json()[\"data\"][\"dealFlow\"][\"dealsAwaitingMySignature\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`query DealsAwaitingMySignature {\n    dealFlow {\n      dealsAwaitingMySignature {\n        id\n        status\n        name\n        proposer { id name }\n        parties { entityId role }\n        createdAt\n      }\n    }\n  }`\n);\nconsole.log(data.dealFlow.dealsAwaitingMySignature);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "query DealsAwaitingMySignature {\n  dealFlow {\n    dealsAwaitingMySignature {\n      id\n      status\n      name\n      proposer { id name }\n      parties { entityId role }\n      createdAt\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "signDeal",
                "relation": "next"
              },
              {
                "operation": "myInbox",
                "relation": "sibling"
              },
              {
                "operation": "dealsByParty",
                "relation": "sibling"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "myInbox",
            "kind": "query",
            "name": "myInbox",
            "service": "yieldfabric-dms",
            "tags": [
              "Queries"
            ],
            "summary": "Unified inbox — deals to sign + pending party actions",
            "description": "Unified inbox returning the union of `dealsAwaitingMySignature` and\n`myPendingActions`. Front-end issues one query and dispatches on\n`__typename`.\n\nThe returned `InboxItem` is a GraphQL union:\n- `DealAwaitingSignature` — a `Proposed` deal where the caller is a\n  counterparty and hasn't signed.\n- `PendingAction` — a `pending_actions` row in PENDING status whose\n  assignee is the caller's effective entity.\n\n**Auth:** requires a valid JWT.\n\n**Idempotency:** read-only.\n",
            "sdl": "query MyInbox {\n  dealFlow {\n    myInbox {\n      __typename\n      ... on DealAwaitingSignature {\n        id\n        status\n        name\n        proposer { id name }\n        createdAt\n      }\n      ... on PendingAction {\n        id\n        dealId\n        descriptorName\n        status\n        createdAt\n      }\n    }\n  }\n}\n",
            "output": {
              "schema": {
                "type": "array",
                "items": {
                  "oneOf": [
                    {
                      "type": "object",
                      "description": "A deal waiting on the caller's signature. Wraps Deal in a distinct\nGraphQL type so the `InboxItem` union can discriminate.\n",
                      "properties": {
                        "deal": {
                          "type": "object",
                          "required": [
                            "id",
                            "kind",
                            "status",
                            "planHash",
                            "plan",
                            "proposerEntityId",
                            "parties",
                            "versionAt",
                            "deleted",
                            "transactionId",
                            "signatures",
                            "events",
                            "capabilities"
                          ],
                          "properties": {
                            "id": {
                              "type": "string"
                            },
                            "kind": {
                              "type": "string",
                              "description": "Whether this row is a fully-fledged signed deal between two parties or\nan internal orchestration template.\n",
                              "enum": [
                                "SIGNED_DEAL",
                                "ORCHESTRATION"
                              ]
                            },
                            "name": {
                              "type": "string",
                              "nullable": true,
                              "description": "User-supplied label captured at `proposeDeal`. `None` when the\ncaller didn't supply one (orchestration-kind deals are always\n`None` — they're programmatically materialised, not user-named).\n"
                            },
                            "status": {
                              "type": "string",
                              "description": "Lifecycle status of a deal. Maps 1:1 to `data::types::deals::DealStatus`.\n",
                              "enum": [
                                "DRAFT",
                                "PROPOSED",
                                "ACCEPTED",
                                "COUNTER_OFFERED",
                                "REJECTED",
                                "ACTIVE",
                                "COMPLETED",
                                "CANCELLED",
                                "DEFAULTED",
                                "FAILED_AFTER_PARTIAL_EXECUTION"
                              ]
                            },
                            "planHash": {
                              "type": "string"
                            },
                            "plan": {
                              "description": "Arbitrary JSON value (object, array, scalar, or null)."
                            },
                            "proposerEntityId": {
                              "type": "string",
                              "description": "Proposer entity ID. Phase 2g will replace this with `proposer: Entity!`\nstitched from the auth subgraph; v1 exposes the raw ID string.\n"
                            },
                            "parties": {
                              "type": "array",
                              "description": "Counter-signing principals on this deal, in plan-authored order.\nEmpty list for orchestration-kind deals.\n",
                              "items": {
                                "type": "object",
                                "description": "One counter-signing principal on a deal. Returned as part of a Deal's\n`parties` field. The `role` is the user-authored IRI used in the plan\n(e.g. `\"counterparty\"`, `\"lender\"`, `\"borrower\"`, `\"custodian\"`).\n",
                                "required": [
                                  "entityId",
                                  "role"
                                ],
                                "properties": {
                                  "entityId": {
                                    "type": "string"
                                  },
                                  "role": {
                                    "type": "string"
                                  }
                                }
                              }
                            },
                            "parentDealId": {
                              "type": "string",
                              "nullable": true
                            },
                            "cashflowRef": {
                              "type": "string",
                              "nullable": true
                            },
                            "workflowId": {
                              "type": "string",
                              "nullable": true
                            },
                            "versionAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            },
                            "acceptedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            },
                            "completedAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            },
                            "cancelledAt": {
                              "type": "string",
                              "format": "date-time",
                              "description": "ISO-8601 datetime (UTC)."
                            },
                            "deleted": {
                              "type": "boolean"
                            },
                            "transactionId": {
                              "type": "string"
                            },
                            "signatures": {
                              "type": "array",
                              "description": "Signatures attached to this deal, ordered by `signed_at` ASC.\nEmpty list for `Orchestration` deals (no signatures expected).\nRequires `Arc<DealStore>` registered in the schema's context.\n",
                              "items": {
                                "type": "object",
                                "description": "One signature on a deal. Returned as part of a Deal's `signatures` field.\n",
                                "required": [
                                  "dealId",
                                  "role",
                                  "partyEntityId",
                                  "sigPayload",
                                  "signedAt"
                                ],
                                "properties": {
                                  "dealId": {
                                    "type": "string"
                                  },
                                  "role": {
                                    "type": "string"
                                  },
                                  "partyEntityId": {
                                    "type": "string"
                                  },
                                  "sigPayload": {
                                    "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                  },
                                  "signedAt": {
                                    "type": "string",
                                    "format": "date-time",
                                    "description": "ISO-8601 datetime (UTC)."
                                  }
                                }
                              }
                            },
                            "events": {
                              "type": "array",
                              "description": "Audit-log events for this deal, ordered by `sequence` ASC.\nSequences are monotonic-but-not-dense within a deal.\n",
                              "items": {
                                "type": "object",
                                "description": "One audit-log entry for a deal.",
                                "required": [
                                  "dealId",
                                  "sequence",
                                  "eventType",
                                  "payload",
                                  "occurredAt"
                                ],
                                "properties": {
                                  "dealId": {
                                    "type": "string"
                                  },
                                  "sequence": {
                                    "type": "integer",
                                    "description": "Monotonic-but-not-dense within a deal (BIGSERIAL is global)."
                                  },
                                  "eventType": {
                                    "type": "string"
                                  },
                                  "actorEntityId": {
                                    "type": "string",
                                    "nullable": true,
                                    "description": "`None` for system-emitted events (timer firings, scheduler ticks)."
                                  },
                                  "payload": {
                                    "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                  },
                                  "occurredAt": {
                                    "type": "string",
                                    "format": "date-time",
                                    "description": "ISO-8601 datetime (UTC)."
                                  }
                                }
                              }
                            },
                            "capabilities": {
                              "type": "array",
                              "description": "Active (non-revoked) delegation capabilities for this deal.\nRevoked capabilities are filtered out — callers wanting full\nhistory should query a future `capabilityHistory` endpoint.\n",
                              "items": {
                                "type": "object",
                                "required": [
                                  "id",
                                  "dealId",
                                  "grantedByEntityId",
                                  "capabilityKind",
                                  "allowedDescriptors",
                                  "allowedParamConstraints",
                                  "planHashBinding",
                                  "grantedAt"
                                ],
                                "properties": {
                                  "id": {
                                    "type": "string"
                                  },
                                  "dealId": {
                                    "type": "string"
                                  },
                                  "grantedByEntityId": {
                                    "type": "string"
                                  },
                                  "capabilityKind": {
                                    "type": "string"
                                  },
                                  "walletId": {
                                    "type": "string",
                                    "nullable": true
                                  },
                                  "accountAddress": {
                                    "type": "string",
                                    "nullable": true
                                  },
                                  "allowedDescriptors": {
                                    "type": "array",
                                    "items": {
                                      "type": "string"
                                    }
                                  },
                                  "allowedParamConstraints": {
                                    "type": "array",
                                    "items": {
                                      "type": "object",
                                      "description": "One parameter constraint on a capability. Exposed as a typed GraphQL\ntype rather than opaque JSON so clients can render constraints in the\nUI without parsing.\n",
                                      "required": [
                                        "descriptor",
                                        "field",
                                        "kind"
                                      ],
                                      "properties": {
                                        "descriptor": {
                                          "type": "string"
                                        },
                                        "field": {
                                          "type": "string"
                                        },
                                        "kind": {
                                          "description": "Constraint variants. Modeled as a GraphQL union of variant-specific\npayload types so clients can dispatch on `__typename`.\n",
                                          "oneOf": [
                                            {
                                              "type": "object",
                                              "required": [
                                                "value"
                                              ],
                                              "properties": {
                                                "value": {
                                                  "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                                }
                                              }
                                            },
                                            {
                                              "type": "object",
                                              "required": [
                                                "values"
                                              ],
                                              "properties": {
                                                "values": {
                                                  "type": "array",
                                                  "items": {
                                                    "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                                  }
                                                }
                                              }
                                            },
                                            {
                                              "type": "object",
                                              "required": [
                                                "value"
                                              ],
                                              "properties": {
                                                "value": {
                                                  "type": "string"
                                                }
                                              }
                                            },
                                            {
                                              "type": "object",
                                              "required": [
                                                "value"
                                              ],
                                              "properties": {
                                                "value": {
                                                  "type": "string"
                                                }
                                              }
                                            }
                                          ]
                                        }
                                      }
                                    }
                                  },
                                  "planHashBinding": {
                                    "type": "string"
                                  },
                                  "grantedAt": {
                                    "type": "string",
                                    "format": "date-time",
                                    "description": "ISO-8601 datetime (UTC)."
                                  },
                                  "revokedAt": {
                                    "type": "string",
                                    "format": "date-time",
                                    "description": "ISO-8601 datetime (UTC)."
                                  }
                                }
                              }
                            }
                          }
                        }
                      }
                    },
                    {
                      "type": "object",
                      "required": [
                        "id",
                        "dealId",
                        "stepId",
                        "descriptorName",
                        "assigneeKind",
                        "descriptorInputs",
                        "expectedOutputsSchema",
                        "status",
                        "createdAt"
                      ],
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "dealId": {
                          "type": "string"
                        },
                        "workflowId": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Pipeline-runtime workflow id, when known."
                        },
                        "stepId": {
                          "type": "string"
                        },
                        "descriptorName": {
                          "type": "string"
                        },
                        "assigneeKind": {
                          "type": "string",
                          "description": "\"ENTITY\" or \"ACCOUNT_ADDRESS\"."
                        },
                        "assigneeEntityId": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "assigneeAccountAddress": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "descriptorInputs": {
                          "description": "Arbitrary JSON value (object, array, scalar, or null)."
                        },
                        "expectedOutputsSchema": {
                          "description": "Arbitrary JSON value (object, array, scalar, or null)."
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "PENDING",
                            "IN_PROGRESS",
                            "COMPLETED",
                            "CANCELLED",
                            "EXPIRED"
                          ]
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time",
                          "description": "ISO-8601 datetime (UTC)."
                        },
                        "expiresAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "completedAt": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "completedBy": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "outputPayload": {
                          "description": "Arbitrary JSON value (object, array, scalar, or null)."
                        }
                      }
                    }
                  ],
                  "description": "Union of items awaiting the caller's attention. Either a deal awaiting\ntheir signature, or a pending action assigned to them.\n"
                }
              }
            },
            "errors": [
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_myInbox",
              "resource_uri": "yf://deals/inbox",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/deals.yaml#/MyInboxResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{ \"query\": \"query MyInbox { dealFlow { myInbox { __typename ... on DealAwaitingSignature { id name } ... on PendingAction { id dealId descriptorName } } } }\" }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nresp = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"query MyInbox { dealFlow { myInbox { __typename ... on DealAwaitingSignature { id name proposer { id name } createdAt } ... on PendingAction { id dealId descriptorName status createdAt } } } }\",\n    },\n)\nprint(resp.json()[\"data\"][\"dealFlow\"][\"myInbox\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`query MyInbox {\n    dealFlow {\n      myInbox {\n        __typename\n        ... on DealAwaitingSignature {\n          id\n          name\n          proposer { id name }\n          createdAt\n        }\n        ... on PendingAction {\n          id\n          dealId\n          descriptorName\n          status\n          createdAt\n        }\n      }\n    }\n  }`\n);\nconsole.log(data.dealFlow.myInbox);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "query MyInbox {\n  dealFlow {\n    myInbox {\n      __typename\n      ... on DealAwaitingSignature {\n        id\n        status\n        name\n        proposer { id name }\n        createdAt\n      }\n      ... on PendingAction {\n        id\n        dealId\n        descriptorName\n        status\n        createdAt\n      }\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "dealsAwaitingMySignature",
                "relation": "sibling"
              },
              {
                "operation": "myPendingActions",
                "relation": "sibling"
              },
              {
                "operation": "dealsByParty",
                "relation": "sibling"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "myPendingActions",
            "kind": "query",
            "name": "myPendingActions",
            "service": "yieldfabric-dms",
            "tags": [
              "Queries"
            ],
            "summary": "Pending-action inbox for the caller",
            "description": "Caller's pending-action inbox.\n\nReturns every PENDING `pending_actions` row whose `assignee` is the\ncaller's effective entity_id (`acting_as`-aware via\n`caller_entity_id`). ACCOUNT_ADDRESS-assignee rows are NOT surfaced\nhere — they go through `pendingActionsForAddress` (Phase 3e).\n\n**Auth:** requires a valid JWT.\n\n**Idempotency:** read-only.\n",
            "sdl": "query MyPendingActions {\n  dealFlow {\n    myPendingActions {\n      id\n      dealId\n      descriptorName\n      status\n      assignee\n      createdAt\n      expectedOutputsSchema\n    }\n  }\n}\n",
            "output": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "id",
                    "dealId",
                    "stepId",
                    "descriptorName",
                    "assigneeKind",
                    "descriptorInputs",
                    "expectedOutputsSchema",
                    "status",
                    "createdAt"
                  ],
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "dealId": {
                      "type": "string"
                    },
                    "workflowId": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "Pipeline-runtime workflow id, when known."
                    },
                    "stepId": {
                      "type": "string"
                    },
                    "descriptorName": {
                      "type": "string"
                    },
                    "assigneeKind": {
                      "type": "string",
                      "description": "\"ENTITY\" or \"ACCOUNT_ADDRESS\"."
                    },
                    "assigneeEntityId": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "assigneeAccountAddress": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "descriptorInputs": {
                      "description": "Arbitrary JSON value (object, array, scalar, or null)."
                    },
                    "expectedOutputsSchema": {
                      "description": "Arbitrary JSON value (object, array, scalar, or null)."
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "PENDING",
                        "IN_PROGRESS",
                        "COMPLETED",
                        "CANCELLED",
                        "EXPIRED"
                      ]
                    },
                    "createdAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "ISO-8601 datetime (UTC)."
                    },
                    "expiresAt": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "completedAt": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    },
                    "completedBy": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "outputPayload": {
                      "description": "Arbitrary JSON value (object, array, scalar, or null)."
                    }
                  }
                }
              }
            },
            "errors": [
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_myPendingActions",
              "resource_uri": "yf://deals/pending-actions",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/deals.yaml#/MyPendingActionsResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{ \"query\": \"query MyPendingActions { dealFlow { myPendingActions { id dealId descriptorName status } } }\" }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nresp = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"query MyPendingActions { dealFlow { myPendingActions { id dealId descriptorName status assignee createdAt } } }\",\n    },\n)\nprint(resp.json()[\"data\"][\"dealFlow\"][\"myPendingActions\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`query MyPendingActions {\n    dealFlow {\n      myPendingActions {\n        id\n        dealId\n        descriptorName\n        status\n        assignee\n        createdAt\n      }\n    }\n  }`\n);\nconsole.log(data.dealFlow.myPendingActions);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "query MyPendingActions {\n  dealFlow {\n    myPendingActions {\n      id\n      dealId\n      descriptorName\n      status\n      assignee\n      createdAt\n      expectedOutputsSchema\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "myInbox",
                "relation": "sibling"
              },
              {
                "operation": "dealsAwaitingMySignature",
                "relation": "sibling"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "dealActionCatalog",
            "kind": "query",
            "name": "dealActionCatalog",
            "service": "yieldfabric-dms",
            "tags": [
              "Queries"
            ],
            "summary": "List every action descriptor the deal-DAG runtime knows about",
            "description": "Catalog of every descriptor the deal-DAG runtime knows about. Returned\nas a flat list; front-end groups by `domain` for the ActionPalette UI.\nStatic (compiled into the binary), so no pagination needed.\n\n**Auth:** requires a valid JWT (any authenticated caller).\n\n**Idempotency:** read-only.\n",
            "sdl": "query DealActionCatalog {\n  dealFlow {\n    dealActionCatalog {\n      name\n      domain\n      description\n      inputs { name fieldType required editorRequired uiHint }\n      outputs { name fieldType }\n    }\n  }\n}\n",
            "output": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "taskName",
                    "displayName",
                    "description",
                    "domain",
                    "kind",
                    "inputs",
                    "outputs",
                    "typicalPredecessors",
                    "mcpExposable",
                    "surfaces"
                  ],
                  "properties": {
                    "taskName": {
                      "type": "string"
                    },
                    "displayName": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "domain": {
                      "type": "string",
                      "description": "\"contract_flow\" | \"payment_flow\" | \"swap_flow\" | \"pipeline_gate\" | \"token_lifecycle\" | \"notification\" | \"timer\" | \"composite\" | \"document\" | \"approval\" | \"data_capture\" | \"identity\" | \"oracle\" | \"external\"."
                    },
                    "kind": {
                      "type": "string",
                      "description": "\"system\" | \"awaitable\" | \"party\" | \"timer\"."
                    },
                    "inputs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "name",
                          "description",
                          "fieldType",
                          "required"
                        ],
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "fieldType": {
                            "type": "string",
                            "description": "Type repr: \"string\" | \"number\" | \"boolean\" | \"json\" | \"identifier:<domain>\" | \"array:<inner>\" | \"object\"."
                          },
                          "required": {
                            "type": "boolean"
                          },
                          "editorRequired": {
                            "type": [
                              "boolean",
                              "null"
                            ],
                            "description": "Editor-required override (UX-only). Editor uses editorRequired.unwrap_or(required)."
                          },
                          "uiHint": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Optional editor hint: asset_picker, amount_field, entity_picker, wallet_picker, contract_picker, date_input."
                          }
                        }
                      }
                    },
                    "outputs": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "name",
                          "description",
                          "fieldType",
                          "required"
                        ],
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "fieldType": {
                            "type": "string",
                            "description": "Type repr: \"string\" | \"number\" | \"boolean\" | \"json\" | \"identifier:<domain>\" | \"array:<inner>\" | \"object\"."
                          },
                          "required": {
                            "type": "boolean"
                          },
                          "editorRequired": {
                            "type": [
                              "boolean",
                              "null"
                            ],
                            "description": "Editor-required override (UX-only). Editor uses editorRequired.unwrap_or(required)."
                          },
                          "uiHint": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "Optional editor hint: asset_picker, amount_field, entity_picker, wallet_picker, contract_picker, date_input."
                          }
                        }
                      }
                    },
                    "typicalPredecessors": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "mcpExposable": {
                      "type": "boolean"
                    },
                    "surfaces": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "\"deals\" / \"pipelines\" — which builder palettes surface this descriptor."
                    }
                  }
                }
              }
            },
            "errors": [
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_dealActionCatalog",
              "resource_uri": "yf://deals/action-catalog",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/deals.yaml#/DealActionCatalogResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{ \"query\": \"query DealActionCatalog { dealFlow { dealActionCatalog { name domain description } } }\" }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nresp = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"query DealActionCatalog { dealFlow { dealActionCatalog { name domain description inputs { name fieldType required } outputs { name fieldType } } } }\",\n    },\n)\nprint(resp.json()[\"data\"][\"dealFlow\"][\"dealActionCatalog\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`query DealActionCatalog {\n    dealFlow {\n      dealActionCatalog {\n        name\n        domain\n        description\n        inputs { name fieldType required editorRequired uiHint }\n        outputs { name fieldType }\n      }\n    }\n  }`\n);\nconsole.log(data.dealFlow.dealActionCatalog);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "query DealActionCatalog {\n  dealFlow {\n    dealActionCatalog {\n      name\n      domain\n      description\n      inputs { name fieldType required editorRequired uiHint }\n      outputs { name fieldType }\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "analyzePlanCapabilities",
                "relation": "sibling"
              },
              {
                "operation": "projectCashflow",
                "relation": "sibling"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "dealAgreement",
            "kind": "query",
            "name": "dealAgreement",
            "service": "yieldfabric-dms",
            "tags": [
              "Queries"
            ],
            "summary": "Render the deal's agreement projection as Markdown",
            "description": "Render the deal's agreement projection as Markdown.\n\nReturns `null` when no Agreement frame exists yet (the deal is\npre-activation, or the agreement projector has not yet run). The UI\nshows \"agreement document being prepared\" in that case.\n\nThe `kg_id` is derived deterministically from `dealId`, so this\nquery never needs the caller to know about the per-deal KG\nidentifier.\n\n**Auth:** requires a valid JWT.\n\n**Idempotency:** read-only.\n",
            "sdl": "query DealAgreement($dealId: String!) {\n  dealFlow {\n    dealAgreement(dealId: $dealId)\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "dealId"
                ],
                "properties": {
                  "dealId": {
                    "type": "string"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Fetch Markdown agreement for a deal",
                  "value": {
                    "dealId": "DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f"
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Markdown projection of the deal agreement. Null if not yet generated."
              }
            },
            "errors": [
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              },
              {
                "code": "FORBIDDEN",
                "status": 403,
                "description": "Caller is not a party on the deal."
              },
              {
                "code": "NOT_FOUND",
                "status": 404,
                "description": "No deal with the given `dealId`."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_dealAgreement",
              "resource_uri": "yf://deals/agreement",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/deals.yaml#/DealAgreementResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"query DealAgreement($dealId: String!) { dealFlow { dealAgreement(dealId: $dealId) } }\",\n    \"variables\": { \"dealId\": \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\" }\n  }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nresp = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"query DealAgreement($dealId: String!) { dealFlow { dealAgreement(dealId: $dealId) } }\",\n        \"variables\": {\"dealId\": \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\"},\n    },\n)\nprint(resp.json()[\"data\"][\"dealFlow\"][\"dealAgreement\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`query DealAgreement($dealId: String!) {\n    dealFlow {\n      dealAgreement(dealId: $dealId)\n    }\n  }`,\n  { dealId: \"DEAL-7f3a1c8e-2b9d-4c10-9f8e-1a2b3c4d5e6f\" }\n);\nconsole.log(data.dealFlow.dealAgreement);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "query DealAgreement($dealId: String!) {\n  dealFlow {\n    dealAgreement(dealId: $dealId)\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "dealById",
                "relation": "sibling"
              },
              {
                "operation": "dealsByParty",
                "relation": "sibling"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "projectCashflow",
            "kind": "query",
            "name": "projectCashflow",
            "service": "yieldfabric-dms",
            "tags": [
              "Queries"
            ],
            "summary": "Preview the projected cashflow for a plan",
            "description": "Preview the projected cashflow for a plan + cashflow config. Pure\nprojection: no DB writes; can be called pre-proposal to populate the\nCashflowChart on the compose / sign pages.\n\n`plan.deal_terms` must carry the seed values (`loan_balance`,\n`interest_pct`, `arrears`, `total_terms`, `expected_payment_amount`)\nthe state machine reads. Returns an empty list when those are missing\n— same soft-fail contract as `seed_period_projections`.\n\n**Deprecated parameter:** `cashflow_ref`. Post-Phase-1 the\nauthoritative cashflow ref is `plan.cashflow_ref` (the JSON field on\nthe plan envelope) — registry dispatch resolves the engine from there.\nThe argument is kept on the GraphQL surface for backwards compat with\nexisting clients but is silently ignored. Remove in a future schema\nversion.\n\n**Auth:** requires a valid JWT.\n\n**Idempotency:** read-only.\n",
            "sdl": "query ProjectCashflow($plan: JSON!, $cashflowRef: String) {\n  dealFlow {\n    projectCashflow(plan: $plan, cashflowRef: $cashflowRef) {\n      periodIndex\n      startsAt\n      endsAt\n      values\n    }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "plan"
                ],
                "properties": {
                  "plan": {
                    "description": "Arbitrary JSON value (object, array, scalar, or null)."
                  },
                  "cashflowRef": {
                    "type": [
                      "string",
                      "null"
                    ],
                    "description": "Deprecated — use `plan.cashflow_ref`. This argument is ignored by the resolver.\n"
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Project a one-shot loan plan with seed terms",
                  "value": {
                    "plan": {
                      "version": 1,
                      "cashflow_ref": "loan_state_machine_v1",
                      "deal_terms": {
                        "loan_balance": "1000000",
                        "interest_pct": "5.0",
                        "arrears": "0",
                        "total_terms": 12,
                        "expected_payment_amount": "85607"
                      },
                      "nodes": [],
                      "edges": []
                    },
                    "cashflowRef": null
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "periodIndex",
                    "projectedCashflow"
                  ],
                  "properties": {
                    "periodIndex": {
                      "type": "integer"
                    },
                    "projectedCashflow": {
                      "description": "Arbitrary JSON value (object, array, scalar, or null)."
                    }
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Plan JSON failed to parse, or the referenced cashflow engine is unknown."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_projectCashflow",
              "resource_uri": "yf://deals/cashflow-projection",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/deals.yaml#/ProjectCashflowResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"query ProjectCashflow($plan: JSON!) { dealFlow { projectCashflow(plan: $plan) { periodIndex values } } }\",\n    \"variables\": { \"plan\": { \"version\": 1, \"deal_terms\": {} } }\n  }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nresp = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"query ProjectCashflow($plan: JSON!, $cashflowRef: String) { dealFlow { projectCashflow(plan: $plan, cashflowRef: $cashflowRef) { periodIndex startsAt endsAt values } } }\",\n        \"variables\": {\n            \"plan\": {\n                \"version\": 1,\n                \"cashflow_ref\": \"loan_state_machine_v1\",\n                \"deal_terms\": {\n                    \"loan_balance\": \"1000000\",\n                    \"interest_pct\": \"5.0\",\n                    \"arrears\": \"0\",\n                    \"total_terms\": 12,\n                    \"expected_payment_amount\": \"85607\",\n                },\n                \"nodes\": [],\n                \"edges\": [],\n            },\n            \"cashflowRef\": None,\n        },\n    },\n)\nprint(resp.json()[\"data\"][\"dealFlow\"][\"projectCashflow\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`query ProjectCashflow($plan: JSON!, $cashflowRef: String) {\n    dealFlow {\n      projectCashflow(plan: $plan, cashflowRef: $cashflowRef) {\n        periodIndex\n        startsAt\n        endsAt\n        values\n      }\n    }\n  }`,\n  {\n    plan: {\n      version: 1,\n      cashflow_ref: \"loan_state_machine_v1\",\n      deal_terms: {\n        loan_balance: \"1000000\",\n        interest_pct: \"5.0\",\n        arrears: \"0\",\n        total_terms: 12,\n        expected_payment_amount: \"85607\",\n      },\n      nodes: [],\n      edges: [],\n    },\n    cashflowRef: null,\n  }\n);\nconsole.log(data.dealFlow.projectCashflow);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "query ProjectCashflow($plan: JSON!, $cashflowRef: String) {\n  dealFlow {\n    projectCashflow(plan: $plan, cashflowRef: $cashflowRef) {\n      periodIndex\n      startsAt\n      endsAt\n      values\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "analyzePlanCapabilities",
                "relation": "sibling"
              },
              {
                "operation": "dealActionCatalog",
                "relation": "sibling"
              },
              {
                "operation": "proposeDeal",
                "relation": "next"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          },
          {
            "operationId": "analyzePlanCapabilities",
            "kind": "query",
            "name": "analyzePlanCapabilities",
            "service": "yieldfabric-dms",
            "tags": [
              "Queries"
            ],
            "summary": "Preview capability grants a plan would require",
            "description": "Preview the capability grants a plan would require.\n\nPure analysis: walks the plan's action nodes, looks each one up in\nthe `DealActionRegistry`, and emits one `CapabilityRequirement` per\nwallet-touching node. No DB writes, no auth resolution beyond the\nstandard \"must be authenticated\" gate. Used by the UI to show\n\"Capabilities you would grant\" before the user clicks Sign.\n\nThe actual minting of `deal_capabilities` rows lands in Phase 3, when\nthe executor side of the runtime exists to consume them. Today the\nanalyzer's output is pure preview.\n\n**Auth:** requires a valid JWT (any authenticated caller).\n\n**Idempotency:** read-only.\n",
            "sdl": "query AnalyzePlanCapabilities($plan: JSON!) {\n  dealFlow {\n    analyzePlanCapabilities(plan: $plan) {\n      stepId\n      descriptorName\n      walletTarget {\n        kind\n        walletId\n        accountAddress\n      }\n      paramConstraints {\n        field\n        constraint {\n          __typename\n        }\n      }\n      entityHints\n    }\n  }\n}\n",
            "input": {
              "schema": {
                "type": "object",
                "required": [
                  "plan"
                ],
                "properties": {
                  "plan": {
                    "description": "Arbitrary JSON value (object, array, scalar, or null)."
                  }
                }
              },
              "examples": {
                "minimal": {
                  "summary": "Analyse capabilities for a tiny one-step plan",
                  "value": {
                    "plan": {
                      "version": 1,
                      "nodes": [
                        {
                          "id": "send_principal",
                          "descriptor": "instant_send",
                          "inputs": {
                            "from": "$proposer.wallet",
                            "to": "$counterparty.wallet",
                            "amount": "1000000",
                            "asset": "USD"
                          }
                        }
                      ],
                      "edges": []
                    }
                  }
                }
              }
            },
            "output": {
              "schema": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "stepId",
                    "descriptorName",
                    "walletTarget",
                    "paramConstraints",
                    "entityHints"
                  ],
                  "properties": {
                    "stepId": {
                      "type": "string"
                    },
                    "descriptorName": {
                      "type": "string"
                    },
                    "walletTarget": {
                      "type": "object",
                      "required": [
                        "kind"
                      ],
                      "properties": {
                        "kind": {
                          "type": "string"
                        },
                        "accountAddress": {
                          "type": [
                            "string",
                            "null"
                          ]
                        },
                        "walletId": {
                          "type": [
                            "string",
                            "null"
                          ]
                        }
                      }
                    },
                    "paramConstraints": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "description": "One parameter constraint on a capability. Exposed as a typed GraphQL\ntype rather than opaque JSON so clients can render constraints in the\nUI without parsing.\n",
                        "required": [
                          "descriptor",
                          "field",
                          "kind"
                        ],
                        "properties": {
                          "descriptor": {
                            "type": "string"
                          },
                          "field": {
                            "type": "string"
                          },
                          "kind": {
                            "description": "Constraint variants. Modeled as a GraphQL union of variant-specific\npayload types so clients can dispatch on `__typename`.\n",
                            "oneOf": [
                              {
                                "type": "object",
                                "required": [
                                  "value"
                                ],
                                "properties": {
                                  "value": {
                                    "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                  }
                                }
                              },
                              {
                                "type": "object",
                                "required": [
                                  "values"
                                ],
                                "properties": {
                                  "values": {
                                    "type": "array",
                                    "items": {
                                      "description": "Arbitrary JSON value (object, array, scalar, or null)."
                                    }
                                  }
                                }
                              },
                              {
                                "type": "object",
                                "required": [
                                  "value"
                                ],
                                "properties": {
                                  "value": {
                                    "type": "string"
                                  }
                                }
                              },
                              {
                                "type": "object",
                                "required": [
                                  "value"
                                ],
                                "properties": {
                                  "value": {
                                    "type": "string"
                                  }
                                }
                              }
                            ]
                          }
                        }
                      }
                    },
                    "entityHints": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            },
            "errors": [
              {
                "code": "BAD_REQUEST",
                "status": 400,
                "description": "Plan JSON failed to parse, or refers to an unknown descriptor."
              },
              {
                "code": "UNAUTHORIZED",
                "status": 401,
                "description": "Missing or invalid bearer token."
              }
            ],
            "x-mcp": {
              "tool_name": "yieldfabric_analyzePlanCapabilities",
              "resource_uri": "yf://deals/capabilities",
              "idempotent": true,
              "output_schema_ref": "../../components/schemas/deals.yaml#/AnalyzePlanCapabilitiesResponse"
            },
            "x-codeSamples": [
              {
                "lang": "curl",
                "label": "cURL",
                "source": "curl -X POST https://api.yieldfabric.com/graphql \\\n  -H \"Authorization: Bearer $JWT\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\n    \"query\": \"query AnalyzePlanCapabilities($plan: JSON!) { dealFlow { analyzePlanCapabilities(plan: $plan) { stepId descriptorName } } }\",\n    \"variables\": { \"plan\": { \"version\": 1, \"nodes\": [], \"edges\": [] } }\n  }'\n"
              },
              {
                "lang": "python",
                "label": "Python (httpx)",
                "source": "import httpx\n\nresp = httpx.post(\n    \"https://api.yieldfabric.com/graphql\",\n    headers={\"Authorization\": f\"Bearer {JWT}\", \"Content-Type\": \"application/json\"},\n    json={\n        \"query\": \"query AnalyzePlanCapabilities($plan: JSON!) { dealFlow { analyzePlanCapabilities(plan: $plan) { stepId descriptorName walletTarget { kind walletId accountAddress } } } }\",\n        \"variables\": {\n            \"plan\": {\n                \"version\": 1,\n                \"nodes\": [\n                    {\n                        \"id\": \"send_principal\",\n                        \"descriptor\": \"instant_send\",\n                        \"inputs\": {\n                            \"from\": \"$proposer.wallet\",\n                            \"to\": \"$counterparty.wallet\",\n                            \"amount\": \"1000000\",\n                            \"asset\": \"USD\",\n                        },\n                    }\n                ],\n                \"edges\": [],\n            }\n        },\n    },\n)\nprint(resp.json()[\"data\"][\"dealFlow\"][\"analyzePlanCapabilities\"])\n"
              },
              {
                "lang": "typescript",
                "label": "TypeScript (graphql-request)",
                "source": "import { GraphQLClient, gql } from \"graphql-request\";\n\nconst client = new GraphQLClient(\"https://api.yieldfabric.com/graphql\", {\n  headers: { Authorization: `Bearer ${JWT}` },\n});\n\nconst data = await client.request(\n  gql`query AnalyzePlanCapabilities($plan: JSON!) {\n    dealFlow {\n      analyzePlanCapabilities(plan: $plan) {\n        stepId\n        descriptorName\n        walletTarget { kind walletId accountAddress }\n      }\n    }\n  }`,\n  {\n    plan: {\n      version: 1,\n      nodes: [\n        {\n          id: \"send_principal\",\n          descriptor: \"instant_send\",\n          inputs: {\n            from: \"$proposer.wallet\",\n            to: \"$counterparty.wallet\",\n            amount: \"1000000\",\n            asset: \"USD\",\n          },\n        },\n      ],\n      edges: [],\n    },\n  }\n);\nconsole.log(data.dealFlow.analyzePlanCapabilities);\n"
              },
              {
                "lang": "graphql",
                "label": "GraphQL (Playground)",
                "source": "query AnalyzePlanCapabilities($plan: JSON!) {\n  dealFlow {\n    analyzePlanCapabilities(plan: $plan) {\n      stepId\n      descriptorName\n      walletTarget {\n        kind\n        walletId\n        accountAddress\n      }\n      paramConstraints {\n        field\n        constraint {\n          __typename\n        }\n      }\n      entityHints\n    }\n  }\n}\n"
              }
            ],
            "x-related": [
              {
                "operation": "projectCashflow",
                "relation": "sibling"
              },
              {
                "operation": "dealActionCatalog",
                "relation": "sibling"
              },
              {
                "operation": "proposeDeal",
                "relation": "next"
              },
              {
                "guide": "deal-lifecycle",
                "relation": "concept"
              }
            ]
          }
        ]
      }
    },
    "/api/users/{user_id}/messages": {
      "get": {
        "operationId": "getUserMessages",
        "summary": "Get user messages with filtering",
        "description": "Retrieve messages for a specific user with optional filtering.",
        "tags": [
          "Messages (REST)"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "User id."
          },
          {
            "name": "message_type",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "description": "Discriminator the consumer pipeline uses to route a message.\n**Open-ended enum** at the API level — the variant set is\nmaintained server-side and grows with platform features.\nRepresentative variants span account/identity (`DeployAccount`,\n`RegisterIdentity`, `AddOwner`), payments (`Deposit`, `Withdraw`,\n`Send`), obligations (`CreateObligation`, `AcceptObligation`,\n`TransferObligation`, `CancelObligation`), swaps (`CreateSwap`,\n`CompleteSwap`, `CancelSwap`, `RepurchaseSwap`,\n`ExpireCollateral`), groups (`AddMember`, `RemoveMember`), and\ntokens (`DeployToken`, `CompliantTokenMint`,\n`CompliantTokenBurn`). Treat this field as a free-form string at\nthe API level; consumers validate against the source-of-truth\nenum.\n"
            }
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "Pending",
                "Validating",
                "Executing",
                "Completed",
                "Failed",
                "Retrying"
              ]
            }
          },
          {
            "name": "chain_id",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "date_from",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "date_to",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 100
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "id",
                      "user_id",
                      "chain_id",
                      "message_type",
                      "data",
                      "executing",
                      "executed",
                      "response",
                      "idempotency_key",
                      "created_at"
                    ],
                    "properties": {
                      "id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "user_id": {
                        "type": "string"
                      },
                      "chain_id": {
                        "type": "string"
                      },
                      "message_type": {
                        "type": "string",
                        "description": "Discriminator the consumer pipeline uses to route a message.\n**Open-ended enum** at the API level — the variant set is\nmaintained server-side and grows with platform features.\nRepresentative variants span account/identity (`DeployAccount`,\n`RegisterIdentity`, `AddOwner`), payments (`Deposit`, `Withdraw`,\n`Send`), obligations (`CreateObligation`, `AcceptObligation`,\n`TransferObligation`, `CancelObligation`), swaps (`CreateSwap`,\n`CompleteSwap`, `CancelSwap`, `RepurchaseSwap`,\n`ExpireCollateral`), groups (`AddMember`, `RemoveMember`), and\ntokens (`DeployToken`, `CompliantTokenMint`,\n`CompliantTokenBurn`). Treat this field as a free-form string at\nthe API level; consumers validate against the source-of-truth\nenum.\n"
                      },
                      "data": {
                        "type": "object"
                      },
                      "executing": {
                        "type": "boolean"
                      },
                      "executed": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "format": "date-time"
                      },
                      "response": {
                        "type": [
                          "object",
                          "null"
                        ],
                        "description": "Canonical lifecycle/result envelope. A failed message is retryable\nonly when the server exposes `can_reexecute: true`; clients must not\ninfer capability from `success: false` alone.\n",
                        "properties": {
                          "can_reexecute": {
                            "type": "boolean",
                            "description": "True only for an eligible failed Automatic Retrieve after its failure post-processing has settled. `/retry` remains authoritative and rechecks all fences."
                          }
                        }
                      },
                      "idempotency_key": {
                        "type": "string"
                      },
                      "created_at": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed request or invalid field at the HTTP layer (pre-GraphQL).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "malformed-json": {
                    "summary": "JSON parse error",
                    "value": {
                      "error": {
                        "code": "BAD_REQUEST",
                        "message": "request body is not valid JSON"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, expired, or wrong-audience bearer JWT. Applies to\nboth user tokens (validated by calling auth's `/protected/jwt`) and\nservice tokens (validated locally against the shared `JWT_SECRET`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "no-token": {
                    "summary": "Missing Authorization header",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "missing bearer token"
                      }
                    }
                  },
                  "wrong-audience-user": {
                    "summary": "User JWT aud does not include payments",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token audience does not include 'payments' or 'default'"
                      }
                    }
                  },
                  "wrong-audience-service": {
                    "summary": "Service JWT presented with the wrong scoped audience",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "service token audience must be 'payments-service'"
                      }
                    }
                  },
                  "expired": {
                    "summary": "JWT exp in the past",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token expired"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (entity, wallet, payment, contract, swap, deal).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error. Treat as transient; safe to retry with the same idempotency_key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://pay.test.yieldfabric.com/api/users/{user_id}/messages \\\n  -H \"Authorization: Bearer $TOKEN\""
          },
          {
            "lang": "typescript",
            "label": "TypeScript",
            "source": "const resp = await fetch('https://pay.test.yieldfabric.com/api/users/{user_id}/messages', {\n  method: 'GET',\n  headers: { 'Authorization': `Bearer ${process.env.TOKEN}` },\n});\nconst data = await resp.json();"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "import httpx, os\nheaders = {'Authorization': f'Bearer {os.environ[\"TOKEN\"]}'}\nurl = 'https://pay.test.yieldfabric.com/api/users/{user_id}/messages'\nresp = httpx.get(url, headers=headers)\nresp.raise_for_status()\ndata = resp.json()"
          }
        ]
      }
    },
    "/api/users/{user_id}/messages/{message_id}": {
      "get": {
        "operationId": "getUserMessage",
        "summary": "Get specific message",
        "description": "Returns the message row PLUS its graph post-processing settlement\nfields (merged additively into the same object).\n\n**`executed` ≠ settled.** `executed` is set when the CHAIN\ntransaction lands; the graph consumer then still materializes\napplication state (Contract/Token/payment rows). The stored\n`response.status` is written `\"completed\"` at execution-store time,\nso it cannot distinguish the two. Pollers whose next step reads\npost-processor-written rows (e.g. querying a contract right after\n`createObligation` settles) MUST wait for `post_processed_at`\ninstead of `executed` — returning at `executed` races the\npost-processor by ~0.1–2s.\n\nTerminal settlement predicate:\n- settled: `post_processed_at != null`\n- failed: `response.error` present, or `post_processing_error`\n  present while `post_processed_at` is null (transient failures\n  auto-retry via the reconciler; `post_processing_error_kind =\n  'unrecoverable'` means DLQ — operator redrive only).\n\nThe settlement fields are best-effort: if the lookup fails the\nlegacy shape (no extra fields) is served, and old clients that\nonly read `executed` are unaffected.\n",
        "tags": [
          "Messages (REST)"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "message_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "allOf": [
                    {
                      "type": "object",
                      "required": [
                        "id",
                        "user_id",
                        "chain_id",
                        "message_type",
                        "data",
                        "executing",
                        "executed",
                        "response",
                        "idempotency_key",
                        "created_at"
                      ],
                      "properties": {
                        "id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "user_id": {
                          "type": "string"
                        },
                        "chain_id": {
                          "type": "string"
                        },
                        "message_type": {
                          "type": "string",
                          "description": "Discriminator the consumer pipeline uses to route a message.\n**Open-ended enum** at the API level — the variant set is\nmaintained server-side and grows with platform features.\nRepresentative variants span account/identity (`DeployAccount`,\n`RegisterIdentity`, `AddOwner`), payments (`Deposit`, `Withdraw`,\n`Send`), obligations (`CreateObligation`, `AcceptObligation`,\n`TransferObligation`, `CancelObligation`), swaps (`CreateSwap`,\n`CompleteSwap`, `CancelSwap`, `RepurchaseSwap`,\n`ExpireCollateral`), groups (`AddMember`, `RemoveMember`), and\ntokens (`DeployToken`, `CompliantTokenMint`,\n`CompliantTokenBurn`). Treat this field as a free-form string at\nthe API level; consumers validate against the source-of-truth\nenum.\n"
                        },
                        "data": {
                          "type": "object"
                        },
                        "executing": {
                          "type": "boolean"
                        },
                        "executed": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time"
                        },
                        "response": {
                          "type": [
                            "object",
                            "null"
                          ],
                          "description": "Canonical lifecycle/result envelope. A failed message is retryable\nonly when the server exposes `can_reexecute: true`; clients must not\ninfer capability from `success: false` alone.\n",
                          "properties": {
                            "can_reexecute": {
                              "type": "boolean",
                              "description": "True only for an eligible failed Automatic Retrieve after its failure post-processing has settled. `/retry` remains authoritative and rechecks all fences."
                            }
                          }
                        },
                        "idempotency_key": {
                          "type": "string"
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      }
                    },
                    {
                      "type": "object",
                      "properties": {
                        "post_processed_at": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "format": "date-time",
                          "description": "Set exactly once, on the first successful graph post-processing run. Non-null ⇒ application state for this message is fully materialized and readable."
                        },
                        "post_processing_attempts": {
                          "type": "integer",
                          "description": "Post-processing attempt counter (DLQ at 3)."
                        },
                        "post_processing_error": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Last attempt's error; cleared on success."
                        },
                        "post_processing_error_kind": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "enum": [
                            "transient",
                            "unrecoverable",
                            null
                          ],
                          "description": "transient = reconciler will retry; unrecoverable = DLQ (operator redrive only)."
                        }
                      }
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Malformed request or invalid field at the HTTP layer (pre-GraphQL).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "malformed-json": {
                    "summary": "JSON parse error",
                    "value": {
                      "error": {
                        "code": "BAD_REQUEST",
                        "message": "request body is not valid JSON"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, expired, or wrong-audience bearer JWT. Applies to\nboth user tokens (validated by calling auth's `/protected/jwt`) and\nservice tokens (validated locally against the shared `JWT_SECRET`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "no-token": {
                    "summary": "Missing Authorization header",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "missing bearer token"
                      }
                    }
                  },
                  "wrong-audience-user": {
                    "summary": "User JWT aud does not include payments",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token audience does not include 'payments' or 'default'"
                      }
                    }
                  },
                  "wrong-audience-service": {
                    "summary": "Service JWT presented with the wrong scoped audience",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "service token audience must be 'payments-service'"
                      }
                    }
                  },
                  "expired": {
                    "summary": "JWT exp in the past",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token expired"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (entity, wallet, payment, contract, swap, deal).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error. Treat as transient; safe to retry with the same idempotency_key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://pay.test.yieldfabric.com/api/users/{user_id}/messages/{message_id} \\\n  -H \"Authorization: Bearer $TOKEN\""
          },
          {
            "lang": "typescript",
            "label": "TypeScript",
            "source": "const resp = await fetch('https://pay.test.yieldfabric.com/api/users/{user_id}/messages/{message_id}', {\n  method: 'GET',\n  headers: { 'Authorization': `Bearer ${process.env.TOKEN}` },\n});\nconst data = await resp.json();"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "import httpx, os\nheaders = {'Authorization': f'Bearer {os.environ[\"TOKEN\"]}'}\nurl = 'https://pay.test.yieldfabric.com/api/users/{user_id}/messages/{message_id}'\nresp = httpx.get(url, headers=headers)\nresp.raise_for_status()\ndata = resp.json()"
          }
        ]
      }
    },
    "/api/users/{user_id}/messages/{message_id}/retry": {
      "post": {
        "operationId": "retryFailedMessage",
        "summary": "Redrive a failed canonical payment retrieval",
        "description": "Re-executes the same failed payment `Retrieve` MQ message after the\ncondition that caused its recorded failed/reverted chain execution has\nbeen corrected. The\noperation preserves\n`message_id`; it does not allocate a second business operation or bypass\nthe original idempotency identity.\n\nThe authenticated effective entity (`acting_as` for a delegated group,\notherwise `sub`) must own the message. The redrive is placed at the head\nof that wallet's sequential partition, creates a fresh validation\nattempt, rebuilds any transaction/proof from current state, and resets\nthe prior terminal post-processing lifecycle so a later successful\noutcome is projected exactly once.\n\nThis is not a generic operation or validation replay. Only `Retrieve`\ncurrently has an audited in-place redrive contract. Every other message\ntype must be submitted as a corrected fresh operation because its\nresolver may own domain reservation state that MQ replay cannot rebuild.\nA message that failed before\nproducing a failed execution result must be corrected and submitted as\na fresh command; direct-relay operations are excluded for the same\nreason.\n\nThe failed attempt's graph post-processing must settle first. This\npreserves its reverted physical-ledger projection and failure\nnotifications before the canonical lifecycle is reset.\n\nCanonical redrive is Automatic-only. Manual signature material is\nattempt-bound; a failed Manual operation must be submitted as a fresh\ncommand so a delayed browser signature cannot cross attempts.\n\nRedrive is rejected while a chain submission is still unresolved. Let\njournal recovery settle `prepared`, `broadcasted`, or\n`receipt_recorded` attempts before retrying; generating a second\ntransaction in that state could double-submit.\n\nRedrive is also rejected if any execution attempt already succeeded on\nchain. A finalize/outbox/graph-projection failure after successful chain\nexecution must be recovered by the automatic post-processing reconciler\nor the operator-only `POST /admin/post-processing/redrive/{message_id}`\npath; repeating the chain transaction could duplicate its side effect.\n",
        "tags": [
          "Messages (REST)"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Route entity id. Authorization is derived from the validated JWT."
          },
          {
            "name": "message_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "execution_mode": {
                    "type": "string",
                    "enum": [
                      "Automatic"
                    ],
                    "default": "Automatic"
                  }
                }
              },
              "examples": {
                "automatic": {
                  "value": {
                    "execution_mode": "Automatic"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The canonical message was restored to its wallet queue.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "message",
                    "message_id",
                    "execution_mode"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "message": {
                      "type": "string"
                    },
                    "message_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "execution_mode": {
                      "type": "string",
                      "enum": [
                        "Automatic"
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Message type other than `Retrieve`, Non-Automatic mode, no active failed chain-execution attempt, unsettled failure post-processing, active execution, unresolved chain submission, or an already-successful chain execution that requires post-processing recovery instead."
          },
          "401": {
            "description": "Missing or invalid bearer token. This route currently returns an empty body."
          },
          "404": {
            "description": "Message not found or not owned by the authenticated effective entity."
          },
          "409": {
            "description": "The user JWT has missing or different chain affinity for this payments instance (`CHAIN_MODE_MISMATCH`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error",
                    "code"
                  ],
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "const": "CHAIN_MODE_MISMATCH"
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "Request `Content-Type` is not `application/json`."
          },
          "422": {
            "description": "JSON body does not match the retry request schema."
          },
          "500": {
            "description": "Message lookup, queue staging, or redrive persistence failed. This route currently returns an empty body."
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X POST https://pay.test.yieldfabric.com/api/users/{user_id}/messages/{message_id}/retry \\\n  -H \"Authorization: Bearer $TOKEN\" \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"execution_mode\":\"Automatic\"}'"
          }
        ]
      }
    },
    "/api/users/{user_id}/messages/{message_id}/can-cancel": {
      "get": {
        "operationId": "canCancelMessage",
        "summary": "Check whether an MQ message can be canceled off-chain",
        "description": "Returns the authoritative cancellation capability for the authenticated\neffective entity. The route `user_id` is not an authority input; ownership\ncomes from the validated JWT (`acting_as` for delegation, otherwise `sub`).\n\nCancellation is deliberately pre-execution only. Pending validation,\nvalidated, manual-signature, and approval-wait states may be cancelable.\nTerminal/unknown states, an active execution generation, or an unresolved\nchain-submission journal are denied.\n\n`Retrieve` is always denied by this generic MQ endpoint. A Retrieve owns a\ndurable payment-generation claim in the obligations/core domain, which MQ\ncannot release atomically; abandoning it requires a future domain-level\npayment-claim operation.\n",
        "tags": [
          "Messages (REST)"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Routing id only; JWT effective entity is authoritative."
          },
          {
            "name": "message_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Cancellation capability, including false for a non-owned or unsafe message.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "can_cancel",
                    "message_id"
                  ],
                  "properties": {
                    "can_cancel": {
                      "type": "boolean"
                    },
                    "reason": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "message_id": {
                      "type": "string",
                      "format": "uuid"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid message UUID."
          },
          "401": {
            "description": "Missing, malformed, expired, or wrong-audience bearer JWT. Applies to\nboth user tokens (validated by calling auth's `/protected/jwt`) and\nservice tokens (validated locally against the shared `JWT_SECRET`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "no-token": {
                    "summary": "Missing Authorization header",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "missing bearer token"
                      }
                    }
                  },
                  "wrong-audience-user": {
                    "summary": "User JWT aud does not include payments",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token audience does not include 'payments' or 'default'"
                      }
                    }
                  },
                  "wrong-audience-service": {
                    "summary": "Service JWT presented with the wrong scoped audience",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "service token audience must be 'payments-service'"
                      }
                    }
                  },
                  "expired": {
                    "summary": "JWT exp in the past",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token expired"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error. Treat as transient; safe to retry with the same idempotency_key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/users/{user_id}/messages/{message_id}/cancel": {
      "post": {
        "operationId": "cancelMessage",
        "summary": "Cancel eligible pre-execution MQ work",
        "description": "Atomically marks an owned, eligible message canceled and removes/releases\nthe exact local queued or in-flight item. Ownership, lifecycle state,\nactive execution rows, and chain-journal state are rechecked under the\nsame per-message database advisory fence used by execution and redrive.\n\nThis is not a failed-message cleanup API: failed/completed/canceled work\nis terminal. It also cannot cancel `Retrieve`; use the payment-domain\nlifecycle rather than orphaning its durable payment-generation claim.\n",
        "tags": [
          "Messages (REST)"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Routing id only; JWT effective entity is authoritative."
          },
          {
            "name": "message_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "reason": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              },
              "examples": {
                "user_request": {
                  "value": {
                    "reason": "No longer required"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Message was canceled before execution handoff.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "message",
                    "message_id"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "message": {
                      "type": "string"
                    },
                    "message_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "reason": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid UUID or message is not safely cancelable."
          },
          "401": {
            "description": "Missing, malformed, expired, or wrong-audience bearer JWT. Applies to\nboth user tokens (validated by calling auth's `/protected/jwt`) and\nservice tokens (validated locally against the shared `JWT_SECRET`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "no-token": {
                    "summary": "Missing Authorization header",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "missing bearer token"
                      }
                    }
                  },
                  "wrong-audience-user": {
                    "summary": "User JWT aud does not include payments",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token audience does not include 'payments' or 'default'"
                      }
                    }
                  },
                  "wrong-audience-service": {
                    "summary": "Service JWT presented with the wrong scoped audience",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "service token audience must be 'payments-service'"
                      }
                    }
                  },
                  "expired": {
                    "summary": "JWT exp in the past",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token expired"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Message not found or not owned by the authenticated effective entity."
          },
          "415": {
            "description": "Request `Content-Type` is not `application/json`."
          },
          "422": {
            "description": "JSON body does not match the cancellation request schema."
          },
          "500": {
            "description": "Unexpected server error. Treat as transient; safe to retry with the same idempotency_key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/users/{user_id}/messages/{message_id}/unsigned-transaction": {
      "get": {
        "operationId": "getUnsignedTransaction",
        "summary": "Get the current manual-signature transaction",
        "description": "Returns the current unsigned transaction and its signing hash for an\nowned message parked in `Manual` / `manual_signature` state.\n\n`unsigned_transaction_id` is an attempt-generation token. A signer must\necho this exact value to `submit-signed-message`; it changes whenever\nthe unsigned transaction is rebuilt, so a delayed signature from an old\nbrowser tab cannot authorize a replacement attempt.\n\nFor an external-key nested group session the response also carries\n`authorization_binding`. Wallets must verify that exact object against\nthe active JWT before prompting: actor, target group, delegation\ngeneration, `[A,B]` path, immutable membership edge, and signer\nkey/address/scheme/custody must all match. It is absent for ordinary\nManual sessions.\n",
        "tags": [
          "Messages (REST)"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "message_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Current attempt-bound unsigned transaction.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "id",
                    "unsigned_transaction_id",
                    "message_hash"
                  ],
                  "properties": {
                    "id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Native unsigned-transaction identifier."
                    },
                    "unsigned_transaction_id": {
                      "type": "string",
                      "format": "uuid",
                      "description": "Attempt token required by signature submission; currently identical to `id`."
                    },
                    "message_hash": {
                      "type": "string",
                      "description": "Hex-encoded 32-byte message hash to sign."
                    },
                    "authorization_binding": {
                      "type": "object",
                      "additionalProperties": false,
                      "required": [
                        "actor_sub",
                        "acting_as",
                        "delegation_token_id",
                        "delegation_path",
                        "authority_source",
                        "membership_edge",
                        "signer_key_id",
                        "signer_address",
                        "signer_scheme",
                        "signer_custody"
                      ],
                      "properties": {
                        "actor_sub": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "acting_as": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "delegation_token_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "delegation_path": {
                          "type": "array",
                          "minItems": 2,
                          "maxItems": 2,
                          "items": {
                            "type": "string",
                            "format": "uuid"
                          }
                        },
                        "authority_source": {
                          "type": "string",
                          "const": "nft_membership"
                        },
                        "membership_edge": {
                          "type": "object",
                          "additionalProperties": false,
                          "required": [
                            "parent_group_id",
                            "child_group_id",
                            "chain_id",
                            "credential_contract",
                            "token_id"
                          ],
                          "properties": {
                            "parent_group_id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "child_group_id": {
                              "type": "string",
                              "format": "uuid"
                            },
                            "chain_id": {
                              "type": "string"
                            },
                            "credential_contract": {
                              "type": "string",
                              "pattern": "^0x[0-9a-f]{40}$"
                            },
                            "token_id": {
                              "type": "string",
                              "pattern": "^[1-9][0-9]*$"
                            }
                          }
                        },
                        "signer_key_id": {
                          "type": "string",
                          "format": "uuid"
                        },
                        "signer_address": {
                          "type": "string",
                          "pattern": "^0x[0-9a-f]{40}$"
                        },
                        "signer_scheme": {
                          "type": "string",
                          "const": "account_ecdsa65_v1"
                        },
                        "signer_custody": {
                          "type": "string",
                          "const": "external"
                        }
                      }
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, expired, or wrong-audience bearer JWT. Applies to\nboth user tokens (validated by calling auth's `/protected/jwt`) and\nservice tokens (validated locally against the shared `JWT_SECRET`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "no-token": {
                    "summary": "Missing Authorization header",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "missing bearer token"
                      }
                    }
                  },
                  "wrong-audience-user": {
                    "summary": "User JWT aud does not include payments",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token audience does not include 'payments' or 'default'"
                      }
                    }
                  },
                  "wrong-audience-service": {
                    "summary": "Service JWT presented with the wrong scoped audience",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "service token audience must be 'payments-service'"
                      }
                    }
                  },
                  "expired": {
                    "summary": "JWT exp in the past",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token expired"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (entity, wallet, payment, contract, swap, deal).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Message is no longer awaiting a signature for this Manual attempt."
          },
          "500": {
            "description": "Unexpected server error. Treat as transient; safe to retry with the same idempotency_key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/users/{user_id}/messages/{message_id}/sign": {
      "post": {
        "operationId": "signManualMessage",
        "summary": "Sign the current transaction with the server-side vault",
        "description": "Signs the current owned manual-signature transaction. The response\nincludes `unsigned_transaction_id`; callers must pass it unchanged with\nthe returned signature to `submit-signed-message`.\n",
        "tags": [
          "Messages (REST)"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "message_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Signature and the exact generation that produced it.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "message",
                    "message_id",
                    "unsigned_transaction_id",
                    "signature",
                    "message_hash"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "message": {
                      "type": "string"
                    },
                    "message_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "unsigned_transaction_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "signature": {
                      "type": "string"
                    },
                    "message_hash": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, expired, or wrong-audience bearer JWT. Applies to\nboth user tokens (validated by calling auth's `/protected/jwt`) and\nservice tokens (validated locally against the shared `JWT_SECRET`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "no-token": {
                    "summary": "Missing Authorization header",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "missing bearer token"
                      }
                    }
                  },
                  "wrong-audience-user": {
                    "summary": "User JWT aud does not include payments",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token audience does not include 'payments' or 'default'"
                      }
                    }
                  },
                  "wrong-audience-service": {
                    "summary": "Service JWT presented with the wrong scoped audience",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "service token audience must be 'payments-service'"
                      }
                    }
                  },
                  "expired": {
                    "summary": "JWT exp in the past",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token expired"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (entity, wallet, payment, contract, swap, deal).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "Message is no longer awaiting a signature for this Manual attempt."
          },
          "500": {
            "description": "Unexpected server error. Treat as transient; safe to retry with the same idempotency_key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/users/{user_id}/messages/{message_id}/submit-signed-message": {
      "post": {
        "operationId": "submitSignedMessage",
        "summary": "Submit an attempt-bound manual signature",
        "description": "Enqueues a signed transaction only when `unsigned_transaction_id`\nmatches the current stored unsigned transaction. The comparison occurs\nunder the same per-message advisory lease used by redrive and before\ncredentials or execution state are mutated.\n",
        "tags": [
          "Messages (REST)"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "message_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "signature",
                  "unsigned_transaction_id"
                ],
                "properties": {
                  "signature": {
                    "type": "string",
                    "pattern": "^0x[0-9a-fA-F]+$"
                  },
                  "unsigned_transaction_id": {
                    "type": "string",
                    "format": "uuid"
                  }
                }
              },
              "example": {
                "signature": "0x...",
                "unsigned_transaction_id": "9c32ba2f-8023-4234-8508-ecab5a76b76f"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signature accepted and execution enqueued.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "success",
                    "message",
                    "message_id",
                    "status"
                  ],
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "const": true
                    },
                    "message": {
                      "type": "string"
                    },
                    "message_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string",
                      "const": "executing"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed request or invalid field at the HTTP layer (pre-GraphQL).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "malformed-json": {
                    "summary": "JSON parse error",
                    "value": {
                      "error": {
                        "code": "BAD_REQUEST",
                        "message": "request body is not valid JSON"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, expired, or wrong-audience bearer JWT. Applies to\nboth user tokens (validated by calling auth's `/protected/jwt`) and\nservice tokens (validated locally against the shared `JWT_SECRET`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "no-token": {
                    "summary": "Missing Authorization header",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "missing bearer token"
                      }
                    }
                  },
                  "wrong-audience-user": {
                    "summary": "User JWT aud does not include payments",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token audience does not include 'payments' or 'default'"
                      }
                    }
                  },
                  "wrong-audience-service": {
                    "summary": "Service JWT presented with the wrong scoped audience",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "service token audience must be 'payments-service'"
                      }
                    }
                  },
                  "expired": {
                    "summary": "JWT exp in the past",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token expired"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (entity, wallet, payment, contract, swap, deal).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "The attempt token is stale or the message is no longer awaiting a signature."
          },
          "422": {
            "description": "Missing or malformed required JSON fields."
          },
          "500": {
            "description": "Unexpected server error. Treat as transient; safe to retry with the same idempotency_key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/users/{user_id}/messages/summary": {
      "get": {
        "operationId": "getUserMessageSummary",
        "summary": "Get message summary",
        "tags": [
          "Messages (REST)"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "total_messages",
                    "pending_messages",
                    "executing_messages",
                    "completed_messages",
                    "failed_messages",
                    "retrying_messages"
                  ],
                  "properties": {
                    "total_messages": {
                      "type": "integer"
                    },
                    "pending_messages": {
                      "type": "integer"
                    },
                    "executing_messages": {
                      "type": "integer"
                    },
                    "completed_messages": {
                      "type": "integer"
                    },
                    "failed_messages": {
                      "type": "integer"
                    },
                    "retrying_messages": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed request or invalid field at the HTTP layer (pre-GraphQL).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "malformed-json": {
                    "summary": "JSON parse error",
                    "value": {
                      "error": {
                        "code": "BAD_REQUEST",
                        "message": "request body is not valid JSON"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, expired, or wrong-audience bearer JWT. Applies to\nboth user tokens (validated by calling auth's `/protected/jwt`) and\nservice tokens (validated locally against the shared `JWT_SECRET`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "no-token": {
                    "summary": "Missing Authorization header",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "missing bearer token"
                      }
                    }
                  },
                  "wrong-audience-user": {
                    "summary": "User JWT aud does not include payments",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token audience does not include 'payments' or 'default'"
                      }
                    }
                  },
                  "wrong-audience-service": {
                    "summary": "Service JWT presented with the wrong scoped audience",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "service token audience must be 'payments-service'"
                      }
                    }
                  },
                  "expired": {
                    "summary": "JWT exp in the past",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token expired"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (entity, wallet, payment, contract, swap, deal).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error. Treat as transient; safe to retry with the same idempotency_key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://pay.test.yieldfabric.com/api/users/{user_id}/messages/summary \\\n  -H \"Authorization: Bearer $TOKEN\""
          },
          {
            "lang": "typescript",
            "label": "TypeScript",
            "source": "const resp = await fetch('https://pay.test.yieldfabric.com/api/users/{user_id}/messages/summary', {\n  method: 'GET',\n  headers: { 'Authorization': `Bearer ${process.env.TOKEN}` },\n});\nconst data = await resp.json();"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "import httpx, os\nheaders = {'Authorization': f'Bearer {os.environ[\"TOKEN\"]}'}\nurl = 'https://pay.test.yieldfabric.com/api/users/{user_id}/messages/summary'\nresp = httpx.get(url, headers=headers)\nresp.raise_for_status()\ndata = resp.json()"
          }
        ]
      }
    },
    "/api/users/{user_id}/messages/history": {
      "get": {
        "operationId": "getUserMessageHistory",
        "summary": "Get message history",
        "tags": [
          "Messages (REST)"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 50
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "id",
                      "user_id",
                      "chain_id",
                      "message_type",
                      "data",
                      "executing",
                      "executed",
                      "response",
                      "idempotency_key",
                      "created_at"
                    ],
                    "properties": {
                      "id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "user_id": {
                        "type": "string"
                      },
                      "chain_id": {
                        "type": "string"
                      },
                      "message_type": {
                        "type": "string",
                        "description": "Discriminator the consumer pipeline uses to route a message.\n**Open-ended enum** at the API level — the variant set is\nmaintained server-side and grows with platform features.\nRepresentative variants span account/identity (`DeployAccount`,\n`RegisterIdentity`, `AddOwner`), payments (`Deposit`, `Withdraw`,\n`Send`), obligations (`CreateObligation`, `AcceptObligation`,\n`TransferObligation`, `CancelObligation`), swaps (`CreateSwap`,\n`CompleteSwap`, `CancelSwap`, `RepurchaseSwap`,\n`ExpireCollateral`), groups (`AddMember`, `RemoveMember`), and\ntokens (`DeployToken`, `CompliantTokenMint`,\n`CompliantTokenBurn`). Treat this field as a free-form string at\nthe API level; consumers validate against the source-of-truth\nenum.\n"
                      },
                      "data": {
                        "type": "object"
                      },
                      "executing": {
                        "type": "boolean"
                      },
                      "executed": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "format": "date-time"
                      },
                      "response": {
                        "type": [
                          "object",
                          "null"
                        ],
                        "description": "Canonical lifecycle/result envelope. A failed message is retryable\nonly when the server exposes `can_reexecute: true`; clients must not\ninfer capability from `success: false` alone.\n",
                        "properties": {
                          "can_reexecute": {
                            "type": "boolean",
                            "description": "True only for an eligible failed Automatic Retrieve after its failure post-processing has settled. `/retry` remains authoritative and rechecks all fences."
                          }
                        }
                      },
                      "idempotency_key": {
                        "type": "string"
                      },
                      "created_at": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed request or invalid field at the HTTP layer (pre-GraphQL).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "malformed-json": {
                    "summary": "JSON parse error",
                    "value": {
                      "error": {
                        "code": "BAD_REQUEST",
                        "message": "request body is not valid JSON"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, expired, or wrong-audience bearer JWT. Applies to\nboth user tokens (validated by calling auth's `/protected/jwt`) and\nservice tokens (validated locally against the shared `JWT_SECRET`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "no-token": {
                    "summary": "Missing Authorization header",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "missing bearer token"
                      }
                    }
                  },
                  "wrong-audience-user": {
                    "summary": "User JWT aud does not include payments",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token audience does not include 'payments' or 'default'"
                      }
                    }
                  },
                  "wrong-audience-service": {
                    "summary": "Service JWT presented with the wrong scoped audience",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "service token audience must be 'payments-service'"
                      }
                    }
                  },
                  "expired": {
                    "summary": "JWT exp in the past",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token expired"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (entity, wallet, payment, contract, swap, deal).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error. Treat as transient; safe to retry with the same idempotency_key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://pay.test.yieldfabric.com/api/users/{user_id}/messages/history \\\n  -H \"Authorization: Bearer $TOKEN\""
          },
          {
            "lang": "typescript",
            "label": "TypeScript",
            "source": "const resp = await fetch('https://pay.test.yieldfabric.com/api/users/{user_id}/messages/history', {\n  method: 'GET',\n  headers: { 'Authorization': `Bearer ${process.env.TOKEN}` },\n});\nconst data = await resp.json();"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "import httpx, os\nheaders = {'Authorization': f'Bearer {os.environ[\"TOKEN\"]}'}\nurl = 'https://pay.test.yieldfabric.com/api/users/{user_id}/messages/history'\nresp = httpx.get(url, headers=headers)\nresp.raise_for_status()\ndata = resp.json()"
          }
        ]
      }
    },
    "/api/users/{user_id}/messages/status/{status}": {
      "get": {
        "operationId": "getUserMessagesByStatus",
        "summary": "Get messages by status",
        "tags": [
          "Messages (REST)"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "Pending",
                "Validating",
                "Executing",
                "Completed",
                "Failed",
                "Retrying"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "id",
                      "user_id",
                      "chain_id",
                      "message_type",
                      "data",
                      "executing",
                      "executed",
                      "response",
                      "idempotency_key",
                      "created_at"
                    ],
                    "properties": {
                      "id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "user_id": {
                        "type": "string"
                      },
                      "chain_id": {
                        "type": "string"
                      },
                      "message_type": {
                        "type": "string",
                        "description": "Discriminator the consumer pipeline uses to route a message.\n**Open-ended enum** at the API level — the variant set is\nmaintained server-side and grows with platform features.\nRepresentative variants span account/identity (`DeployAccount`,\n`RegisterIdentity`, `AddOwner`), payments (`Deposit`, `Withdraw`,\n`Send`), obligations (`CreateObligation`, `AcceptObligation`,\n`TransferObligation`, `CancelObligation`), swaps (`CreateSwap`,\n`CompleteSwap`, `CancelSwap`, `RepurchaseSwap`,\n`ExpireCollateral`), groups (`AddMember`, `RemoveMember`), and\ntokens (`DeployToken`, `CompliantTokenMint`,\n`CompliantTokenBurn`). Treat this field as a free-form string at\nthe API level; consumers validate against the source-of-truth\nenum.\n"
                      },
                      "data": {
                        "type": "object"
                      },
                      "executing": {
                        "type": "boolean"
                      },
                      "executed": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "format": "date-time"
                      },
                      "response": {
                        "type": [
                          "object",
                          "null"
                        ],
                        "description": "Canonical lifecycle/result envelope. A failed message is retryable\nonly when the server exposes `can_reexecute: true`; clients must not\ninfer capability from `success: false` alone.\n",
                        "properties": {
                          "can_reexecute": {
                            "type": "boolean",
                            "description": "True only for an eligible failed Automatic Retrieve after its failure post-processing has settled. `/retry` remains authoritative and rechecks all fences."
                          }
                        }
                      },
                      "idempotency_key": {
                        "type": "string"
                      },
                      "created_at": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed request or invalid field at the HTTP layer (pre-GraphQL).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "malformed-json": {
                    "summary": "JSON parse error",
                    "value": {
                      "error": {
                        "code": "BAD_REQUEST",
                        "message": "request body is not valid JSON"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, expired, or wrong-audience bearer JWT. Applies to\nboth user tokens (validated by calling auth's `/protected/jwt`) and\nservice tokens (validated locally against the shared `JWT_SECRET`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "no-token": {
                    "summary": "Missing Authorization header",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "missing bearer token"
                      }
                    }
                  },
                  "wrong-audience-user": {
                    "summary": "User JWT aud does not include payments",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token audience does not include 'payments' or 'default'"
                      }
                    }
                  },
                  "wrong-audience-service": {
                    "summary": "Service JWT presented with the wrong scoped audience",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "service token audience must be 'payments-service'"
                      }
                    }
                  },
                  "expired": {
                    "summary": "JWT exp in the past",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token expired"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (entity, wallet, payment, contract, swap, deal).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error. Treat as transient; safe to retry with the same idempotency_key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://pay.test.yieldfabric.com/api/users/{user_id}/messages/status/{status} \\\n  -H \"Authorization: Bearer $TOKEN\""
          },
          {
            "lang": "typescript",
            "label": "TypeScript",
            "source": "const resp = await fetch('https://pay.test.yieldfabric.com/api/users/{user_id}/messages/status/{status}', {\n  method: 'GET',\n  headers: { 'Authorization': `Bearer ${process.env.TOKEN}` },\n});\nconst data = await resp.json();"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "import httpx, os\nheaders = {'Authorization': f'Bearer {os.environ[\"TOKEN\"]}'}\nurl = 'https://pay.test.yieldfabric.com/api/users/{user_id}/messages/status/{status}'\nresp = httpx.get(url, headers=headers)\nresp.raise_for_status()\ndata = resp.json()"
          }
        ]
      }
    },
    "/api/users/{user_id}/messages/type/{message_type}": {
      "get": {
        "operationId": "getUserMessagesByType",
        "summary": "Get messages by type",
        "tags": [
          "Messages (REST)"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "user_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "message_type",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "description": "Discriminator the consumer pipeline uses to route a message.\n**Open-ended enum** at the API level — the variant set is\nmaintained server-side and grows with platform features.\nRepresentative variants span account/identity (`DeployAccount`,\n`RegisterIdentity`, `AddOwner`), payments (`Deposit`, `Withdraw`,\n`Send`), obligations (`CreateObligation`, `AcceptObligation`,\n`TransferObligation`, `CancelObligation`), swaps (`CreateSwap`,\n`CompleteSwap`, `CancelSwap`, `RepurchaseSwap`,\n`ExpireCollateral`), groups (`AddMember`, `RemoveMember`), and\ntokens (`DeployToken`, `CompliantTokenMint`,\n`CompliantTokenBurn`). Treat this field as a free-form string at\nthe API level; consumers validate against the source-of-truth\nenum.\n"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 100
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Successful response",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "required": [
                      "id",
                      "user_id",
                      "chain_id",
                      "message_type",
                      "data",
                      "executing",
                      "executed",
                      "response",
                      "idempotency_key",
                      "created_at"
                    ],
                    "properties": {
                      "id": {
                        "type": "string",
                        "format": "uuid"
                      },
                      "user_id": {
                        "type": "string"
                      },
                      "chain_id": {
                        "type": "string"
                      },
                      "message_type": {
                        "type": "string",
                        "description": "Discriminator the consumer pipeline uses to route a message.\n**Open-ended enum** at the API level — the variant set is\nmaintained server-side and grows with platform features.\nRepresentative variants span account/identity (`DeployAccount`,\n`RegisterIdentity`, `AddOwner`), payments (`Deposit`, `Withdraw`,\n`Send`), obligations (`CreateObligation`, `AcceptObligation`,\n`TransferObligation`, `CancelObligation`), swaps (`CreateSwap`,\n`CompleteSwap`, `CancelSwap`, `RepurchaseSwap`,\n`ExpireCollateral`), groups (`AddMember`, `RemoveMember`), and\ntokens (`DeployToken`, `CompliantTokenMint`,\n`CompliantTokenBurn`). Treat this field as a free-form string at\nthe API level; consumers validate against the source-of-truth\nenum.\n"
                      },
                      "data": {
                        "type": "object"
                      },
                      "executing": {
                        "type": "boolean"
                      },
                      "executed": {
                        "type": [
                          "string",
                          "null"
                        ],
                        "format": "date-time"
                      },
                      "response": {
                        "type": [
                          "object",
                          "null"
                        ],
                        "description": "Canonical lifecycle/result envelope. A failed message is retryable\nonly when the server exposes `can_reexecute: true`; clients must not\ninfer capability from `success: false` alone.\n",
                        "properties": {
                          "can_reexecute": {
                            "type": "boolean",
                            "description": "True only for an eligible failed Automatic Retrieve after its failure post-processing has settled. `/retry` remains authoritative and rechecks all fences."
                          }
                        }
                      },
                      "idempotency_key": {
                        "type": "string"
                      },
                      "created_at": {
                        "type": "string",
                        "format": "date-time"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Malformed request or invalid field at the HTTP layer (pre-GraphQL).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "malformed-json": {
                    "summary": "JSON parse error",
                    "value": {
                      "error": {
                        "code": "BAD_REQUEST",
                        "message": "request body is not valid JSON"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, expired, or wrong-audience bearer JWT. Applies to\nboth user tokens (validated by calling auth's `/protected/jwt`) and\nservice tokens (validated locally against the shared `JWT_SECRET`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "no-token": {
                    "summary": "Missing Authorization header",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "missing bearer token"
                      }
                    }
                  },
                  "wrong-audience-user": {
                    "summary": "User JWT aud does not include payments",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token audience does not include 'payments' or 'default'"
                      }
                    }
                  },
                  "wrong-audience-service": {
                    "summary": "Service JWT presented with the wrong scoped audience",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "service token audience must be 'payments-service'"
                      }
                    }
                  },
                  "expired": {
                    "summary": "JWT exp in the past",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token expired"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found (entity, wallet, payment, contract, swap, deal).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected server error. Treat as transient; safe to retry with the same idempotency_key.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -X GET https://pay.test.yieldfabric.com/api/users/{user_id}/messages/type/{message_type} \\\n  -H \"Authorization: Bearer $TOKEN\""
          },
          {
            "lang": "typescript",
            "label": "TypeScript",
            "source": "const resp = await fetch('https://pay.test.yieldfabric.com/api/users/{user_id}/messages/type/{message_type}', {\n  method: 'GET',\n  headers: { 'Authorization': `Bearer ${process.env.TOKEN}` },\n});\nconst data = await resp.json();"
          },
          {
            "lang": "python",
            "label": "Python",
            "source": "import httpx, os\nheaders = {'Authorization': f'Bearer {os.environ[\"TOKEN\"]}'}\nurl = 'https://pay.test.yieldfabric.com/api/users/{user_id}/messages/type/{message_type}'\nresp = httpx.get(url, headers=headers)\nresp.raise_for_status()\ndata = resp.json()"
          }
        ]
      }
    },
    "/api/internal/messages/{message_id}/state": {
      "get": {
        "operationId": "getInternalMessageState",
        "summary": "Read one MQ lifecycle state for auth reconciliation",
        "description": "Looks up a message UUID on the reached payments instance and returns\nonly its lifecycle status plus non-secret chain/operation assertions.\n\nThis endpoint accepts **only** the existing short-lived service JWT whose\nvalidated claims are `kind: service`, `name: auth-internal`\n(`sub = service:auth-internal`, audience `payments-service`). User JWTs\nand every other service identity receive 403. It does not introduce an\nAPI key or a new credential format.\n\n`execution_succeeded` is independent of graph materialization.\nIt is the latest durable `execution_results.success` value joined through\n`execution_messages.original_message_id`; it is `null` when no execution\nresult exists. It is never inferred from lifecycle status or decrypted\nmessage response data. A finalize/DLQ failure can therefore report\n`status: failed` with `execution_succeeded: true`.\n\n`failed` is retryable and is not abandonment. `canceled` is the only\nexplicit abandonment state; `completed` is successful lifecycle\ncompletion. Owner/member journals still confirm final truth through the\nstrict on-chain predicate rather than projecting it from MQ state.\n\nThe message row's `chain_id` must equal the reached payments instance's\nconfigured default chain. A stale or misrouted cross-chain row is rejected\nwith 409 instead of being returned to the caller.\n",
        "tags": [
          "Sister-service REST"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "message_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Minimal message-state projection",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "message_id",
                    "status",
                    "execution_succeeded",
                    "chain_id",
                    "message_type"
                  ],
                  "properties": {
                    "message_id": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "pending",
                        "validating",
                        "awaiting_user_confirmation",
                        "confirmed",
                        "manual_signature",
                        "awaiting_approval",
                        "executing",
                        "post_processing",
                        "completed",
                        "failed",
                        "retrying",
                        "canceled"
                      ]
                    },
                    "execution_succeeded": {
                      "type": [
                        "boolean",
                        "null"
                      ],
                      "description": "Latest `execution_results.success` for this original message. `null`\nmeans no execution result exists. This value is not inferred from\nlifecycle status; `failed` may coexist with `true` when a later\nfinalize/post-processing step failed.\n"
                    },
                    "chain_id": {
                      "type": "string",
                      "description": "Chain stamped on the canonical message row."
                    },
                    "message_type": {
                      "type": "string",
                      "description": "MQ operation enum name (for journal-kind assertion)."
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, malformed, expired, wrong-audience, or invalid-signature JWT.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "code",
                    "message"
                  ],
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "auth_failed",
                        "auth_internal_service_required",
                        "message_not_found",
                        "message_chain_mismatch",
                        "message_state_lookup_failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "Valid JWT, but not the exact `auth-internal` service identity.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "code",
                    "message"
                  ],
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "auth_failed",
                        "auth_internal_service_required",
                        "message_not_found",
                        "message_chain_mismatch",
                        "message_state_lookup_failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "No message with this UUID exists on the reached payments instance.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "code",
                    "message"
                  ],
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "auth_failed",
                        "auth_internal_service_required",
                        "message_not_found",
                        "message_chain_mismatch",
                        "message_state_lookup_failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "The row belongs to a different chain than the reached payments instance.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "code",
                    "message"
                  ],
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "auth_failed",
                        "auth_internal_service_required",
                        "message_not_found",
                        "message_chain_mismatch",
                        "message_state_lookup_failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Broker-database lookup failed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "code",
                    "message"
                  ],
                  "properties": {
                    "code": {
                      "type": "string",
                      "enum": [
                        "auth_failed",
                        "auth_internal_service_required",
                        "message_not_found",
                        "message_chain_mismatch",
                        "message_state_lookup_failed"
                      ]
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/billing/gas-usage": {
      "get": {
        "operationId": "exportGasUsage",
        "summary": "Page the per-transaction gas ledger for billing ingestion",
        "description": "Strict keyset pagination over `(created_at, tx_hash)`. Rows younger\nthan 2 minutes are withheld (safety lag) so pages are stable against\nin-flight inserts. Numeric quantities (`gas_used`,\n`effective_gas_price`, `gas_cost_wei`) are decimal strings — callers\ndo integer math and never re-derive them.\n\nAttribution semantics: `entity_id` mirrors `messages.user_id`, which\nis the GROUP id when the message was submitted under a delegation\nJWT; `actor_user_id` is the acting user's JWT `sub` captured at\nwrite time (null for pre-ledger history or when the JWT was\nunavailable — billing falls back to the group account). Reverted\ntransactions appear with `tx_success: false`; the relayer paid gas\neither way, so they are exported and billable by default.\n",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "after_created_at",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "RFC3339 timestamp of the last-consumed row. Omit for a cold start (epoch)."
          },
          {
            "name": "after_tx_hash",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string"
            },
            "description": "tx_hash of the last-consumed row (tie-break within a timestamp)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 1000,
              "default": 500
            }
          }
        ],
        "responses": {
          "200": {
            "description": "One export page.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "rows",
                    "next_cursor"
                  ],
                  "properties": {
                    "rows": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "tx_hash",
                          "message_id",
                          "entity_id",
                          "chain_id",
                          "message_type",
                          "tx_success",
                          "gas_used",
                          "effective_gas_price",
                          "gas_cost_wei",
                          "created_at"
                        ],
                        "properties": {
                          "tx_hash": {
                            "type": "string"
                          },
                          "message_id": {
                            "type": "string",
                            "format": "uuid"
                          },
                          "entity_id": {
                            "type": "string",
                            "description": "messages.user_id — the group id under delegation, else the user id."
                          },
                          "actor_user_id": {
                            "type": "string",
                            "nullable": true,
                            "description": "Acting user's JWT sub captured at write time; null falls back to group billing."
                          },
                          "wallet_id": {
                            "type": "string",
                            "nullable": true
                          },
                          "chain_id": {
                            "type": "string"
                          },
                          "message_type": {
                            "type": "string"
                          },
                          "tx_success": {
                            "type": "boolean"
                          },
                          "gas_used": {
                            "type": "string",
                            "description": "Decimal string."
                          },
                          "effective_gas_price": {
                            "type": "string",
                            "description": "Decimal string, wei."
                          },
                          "gas_cost_wei": {
                            "type": "string",
                            "description": "gas_used * effective_gas_price, decimal string."
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          }
                        }
                      }
                    },
                    "next_cursor": {
                      "type": "object",
                      "nullable": true,
                      "description": "Present when the page was full (more rows likely available); null means re-poll later from the same position.",
                      "properties": {
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "tx_hash": {
                          "type": "string"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing/invalid bearer token. Body `{ \"error\": \"...\" }`."
          },
          "403": {
            "description": "Caller is neither a service token nor a staff-role user. Body `{ \"error\": \"...\" }`."
          }
        }
      }
    },
    "/mcp": {
      "post": {
        "operationId": "mcpJsonRpc",
        "summary": "Standard MCP endpoint (JSON-RPC 2.0, stateless Streamable HTTP)",
        "description": "One JSON-RPC 2.0 request per POST. Methods: `initialize` (protocol\nnegotiation; `instructions` quote the skill's \"Before you write\"\nrules), `ping`, `tools/list`, `tools/call`. Notifications (no `id`)\nare acknowledged with `202` and an empty body. Batch arrays are\nrefused (`-32600 Batch requests are not supported`); malformed JSON is\n`-32700`; an unknown method is `-32601`; an unknown or not-yet-released\ntool name is `-32602 Unknown tool: <name>` before any side effect.\n\n**Admission.** Every request — `initialize`\nincluded — needs a bearer:\n\n- an OAuth access token whose `aud` names this server's resource URI\n  (`https://pay.test.yieldfabric.com/mcp`), verified locally under the shared\n  secret and then with auth (`/protected/jwt`); or\n- a connector API key (`yf_api_…`, minted with\n  `POST /auth/api-key/generate {\"kind\": \"connector\"}`), exchanged at\n  auth for THIS instance's chain (cached per key + chain for at most\n  60 s).\n\nThe resulting session must be a **connector** session\n(`session_kind == connector`). Anything else — a personal API key, a\nlogin JWT, a delegation JWT, a service token, a token minted for\nanother resource — is `401` with `WWW-Authenticate: Bearer\nresource_metadata=\"https://pay.test.yieldfabric.com/.well-known/oauth-protected-resource\",\nerror=\"invalid_token\"` and a JSON hint (`mint a connector API key … or\nconnect via OAuth`). Never 403. When auth cannot be reached, times\nout or fails while exchanging or validating, the answer is `503`\nwith `Retry-After: 5` and no challenge — retry, do not re-authorize.\n\n**Revocation lag.** Validated claims are reused for at most 60 s and\nan exchanged connector JWT for at most 60 s before auth is asked\nagain, so `POST /auth/api-keys/{id}/revoke` — or any refusal auth\nenforces at `/protected/jwt` — takes effect here within a minute.\n\n**Chain affinity.** A session minted for another chain answers the\n`tools/call` with an `isError` result carrying\n`structuredContent.error.code = CHAIN_MODE_MISMATCH` (the REST\nguard's 409, in JSON-RPC shape). Route the credential to the\nmatching `pay.test…` / `pay.live…` host.\n\n**Origin.** A browser `Origin` header is refused with `403\n{\"error\":\"Origin not allowed\"}` unless the deployment allow-lists it; requests\nwithout `Origin` — every server-side MCP client — are unaffected.\n`MCP-Protocol-Version`: absent ⇒ `2025-03-26`; unsupported ⇒ `400`\nlisting the supported revisions (`2024-11-05` … `2025-11-25`).\n\n**Catalog (19 tools: 14 reads, 4 proposals, `intent_status`).**\nEvery read carries `annotations {readOnlyHint: true, idempotentHint:\ntrue, openWorldHint: false}`; every proposal `{readOnlyHint: false,\ndestructiveHint: false, idempotentHint: true, openWorldHint: false}`\n(nothing on this server is destructive; the destructive\nact is the human's confirmation in the app). Each entry advertises an\n`inputSchema` and an `outputSchema` derived from the tool's response\ntype; every result's `structuredContent` validates against it. The\nwhole serialised result is capped at 256 KiB (`truncated: true`\nbeyond); the list tools (`list_assets`, `list_contacts`,\n`list_connection_requests`) take `limit` (≤ 100) and `cursor` and\nanswer `next_cursor` while more remain.\n\n| Tool | Reads / proposes | Downstream |\n|---|---|---|\n| `whoami` | entity, role, `session_kind`, `chain_id` + `mode` (`LIVE`/`TEST`), wallet id/address, permissions, gates | none (claims) |\n| `wait_for_settlement {message_id, timeout_s ≤ 60}` | `{state: pending\\|executed\\|settled\\|failed, executed_at, post_processed_at, error?, retry_after_s?, …}` — the settled predicate of the message-status endpoint (skill `settlement.md`), server-owned loop, no DB connection held across the wait | MQ (in-process) |\n| `list_assets {limit?, cursor?}`, `get_asset {asset_id}` | the asset catalog of this chain | stores |\n| `list_contacts {limit?, cursor?}`, `get_contact {contact_id}`, `list_connection_requests {status?, limit?, cursor?}` | connections + entity/wallet enrichment | auth identity (on-behalf-of) |\n| `pipeline_list_tasks {domain?}`, `pipeline_describe_task {task_name}`, `pipeline_propose {steps}` (a validator, no side effect), `pipeline_find_predecessors {task_name}` | the deal-plan task registry | none |\n| `yieldfabric_dealAgreement {deal_id}`, `yieldfabric_dealAgreementGraph {deal_id}`, `agreement_next_scheduled_payment {deal_id}` | the deal-flow agreement projection (`dealFlow.dealAgreement*`, served by the agents subgraph) | agents (on-behalf-of) |\n| `propose_send {asset_id, amount, destination_id? \\| destination_wallet_id? \\| contract_id?, obligor?, request_id?, working_group_id?, title?, rationale?}` | proposes `yieldfabric_instant` from this session's wallet on this chain — `{intent_id, workspace_id, status, expires_at, identity_hash?, confirm_url, created}`; `amount` human-readable (scaled at dispatch) | agents (on-behalf-of) |\n| `propose_accept {payment_id, request_id?, working_group_id?, title?, rationale?}` | proposes `yieldfabric_accept` — same output | agents (on-behalf-of) |\n| `propose_swap_credit_for_cash {denomination, amount, obligor, deadline?, request_id?, working_group_id?, title?, rationale?}` | proposes `yieldfabric_swapObligorPayment` — same output | agents (on-behalf-of) |\n| `propose_complete_swap {swap_id, request_id?, working_group_id?, title?, rationale?}` | proposes `yieldfabric_completeSwap` — same output | agents (on-behalf-of) |\n| `intent_status {intent_id, workspace_id? \\| working_group_id?}` | `{intent_id, workspace_id, status, tool_name?, arguments, chain_id?, wallet_id?, actor_entity_id?, expires_at?, approved_at, message_id, result, error, confirm_url, recovery: none\\|in_progress}` — agents' authorised read, scoped to the workspace the intent is filed in (pass the `workspace_id` the proposal returned; default the caller's personal workspace); an intent the caller may not see is `not_found`; the pins and `tool_name` are `null` on a legacy in-app intent | agents (on-behalf-of) |\n\n**Proposals execute nothing.** A `propose_*` tool validates the\ndirect tool's arguments (minus `idempotency_key` — the intent id is\nthe dispatched mutation's idempotency key), pins the chain (this\ninstance's), the wallet (the session's default; a walletless session\nis `CHAIN_ACCOUNT_REQUIRED`) and the actor (`acting_as`, else `sub`)\nfrom the validated claims, and files a `FinancialIntent` with agents\n(`POST /working-groups/{workspace}/intents`; `working_group_id`\ndefaults to the caller's personal workspace, and the output reports\nthe workspace used as `workspace_id`). The account holder confirms\nat `confirm_url` from a direct personal session in the app; agents\ndispatches on the pinned chain under a lease. The same proposal\nwhile one is open returns the same intent (`created: false`); pass a\ndistinct `request_id` for a second identical one. Then\n`intent_status {intent_id, workspace_id}` → `message_id` →\n`wait_for_settlement`.\n\n**Deployment prerequisite.** Every agents-bound tool (the proposals,\n`intent_status`, the agreement reads) mints its on-behalf-of token\nfor `AGENTS_PUBLIC_URL`; the identity tools for `AUTH_PUBLIC_URL`.\nWhen the variable is unset and the fallback is a docker-internal\nservice URL (`https://agents.yieldfabric.com`), the tool is refused up\nfront — `obo_unavailable` (503) naming the variable, no exchange\nattempted — because auth refuses such an audience (`invalid_target`)\nand the callee refuses the token even if it were minted.\n\nThe seven pre-existing direct writes (`yieldfabric_instant`,\n`yieldfabric_accept`, `yieldfabric_swapObligorPayment`,\n`yieldfabric_completeSwap`, `create_connection_request`,\n`accept_connection`, `send_invitation`) are registered REST-only\n(`Release::RestOnly`): absent from this catalog at every release, not\npresent-but-refusing — calling one here is `-32602`. On\n`/api/mcp/tools/call` a connector session is refused\n(`connector_read_only`, 403); other sessions run them as before.\n\n**Tool failures are results.** A parameter error, a not-found, a\ndownstream refusal or an unavailable on-behalf-of exchange comes back\nas `isError: true` with `structuredContent.error {code, message}`\n(`invalid_params`, `not_found`, `downstream_failed`, `obo_unavailable`,\n`obo_refused`, `tool_failed`, `CHAIN_MODE_MISMATCH`,\n`CHAIN_ACCOUNT_REQUIRED`, `intent_refused` — agents 401/403 —,\n`intent_conflict` — agents 409) inside an HTTP 200 JSON-RPC result;\nJSON-RPC `error` objects are reserved for protocol faults.\n",
        "tags": [
          "MCP"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "parameters": [
          {
            "name": "MCP-Protocol-Version",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "2024-11-05",
                "2025-03-26",
                "2025-06-18",
                "2025-11-25"
              ]
            },
            "description": "The revision the client speaks. Absent ⇒ `2025-03-26`."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "jsonrpc",
                  "method"
                ],
                "properties": {
                  "jsonrpc": {
                    "type": "string",
                    "enum": [
                      "2.0"
                    ]
                  },
                  "id": {
                    "description": "Request id; omit for a notification (answered 202).",
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "integer"
                      }
                    ]
                  },
                  "method": {
                    "type": "string",
                    "enum": [
                      "initialize",
                      "ping",
                      "tools/list",
                      "tools/call"
                    ]
                  },
                  "params": {
                    "type": "object"
                  }
                }
              },
              "examples": {
                "initialize": {
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 1,
                    "method": "initialize",
                    "params": {
                      "protocolVersion": "2025-06-18",
                      "clientInfo": {
                        "name": "curl",
                        "version": "0"
                      }
                    }
                  }
                },
                "tools-list": {
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 2,
                    "method": "tools/list"
                  }
                },
                "whoami": {
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 3,
                    "method": "tools/call",
                    "params": {
                      "name": "whoami",
                      "arguments": {}
                    }
                  }
                },
                "wait-for-settlement": {
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 4,
                    "method": "tools/call",
                    "params": {
                      "name": "wait_for_settlement",
                      "arguments": {
                        "message_id": "0f2a7b7c-1111-2222-3333-444444444444",
                        "timeout_s": 30
                      }
                    }
                  }
                },
                "propose-send": {
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 6,
                    "method": "tools/call",
                    "params": {
                      "name": "propose_send",
                      "arguments": {
                        "asset_id": "ASSET-1",
                        "amount": "12.50",
                        "destination_wallet_id": "5e1d9e1a-2222-3333-4444-555555555555",
                        "rationale": "Invoice 42"
                      }
                    }
                  }
                },
                "intent-status": {
                  "value": {
                    "jsonrpc": "2.0",
                    "id": 7,
                    "method": "tools/call",
                    "params": {
                      "name": "intent_status",
                      "arguments": {
                        "intent_id": "6d1f0c2e-5555-6666-7777-888888888888"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A JSON-RPC response (`result` or `error`).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "jsonrpc",
                    "id"
                  ],
                  "properties": {
                    "jsonrpc": {
                      "type": "string",
                      "enum": [
                        "2.0"
                      ]
                    },
                    "id": {
                      "oneOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "integer"
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "result": {
                      "type": "object"
                    },
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "integer"
                        },
                        "message": {
                          "type": "string"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "tools-call-result": {
                    "summary": "A tool result (`whoami`)",
                    "value": {
                      "jsonrpc": "2.0",
                      "id": 3,
                      "result": {
                        "content": [
                          {
                            "type": "text",
                            "text": "{\n  \"entity_id\": \"…\",\n  \"mode\": \"TEST\"\n}"
                          }
                        ],
                        "isError": false,
                        "structuredContent": {
                          "entity_id": "…",
                          "sub": "…",
                          "kind": "user",
                          "role": "User",
                          "session_kind": "connector",
                          "chain_id": "153",
                          "mode": "TEST",
                          "wallet": {
                            "id": "…",
                            "address": "0x…"
                          },
                          "permissions": [
                            "ApiRead"
                          ],
                          "gates": {}
                        }
                      }
                    }
                  },
                  "tool-failure": {
                    "summary": "A tool failure is a result, not a protocol error",
                    "value": {
                      "jsonrpc": "2.0",
                      "id": 4,
                      "result": {
                        "content": [
                          {
                            "type": "text",
                            "text": "{\n  \"error\": {\n    \"code\": \"invalid_params\",\n    \"message\": \"Missing required parameter: message_id\"\n  }\n}"
                          }
                        ],
                        "isError": true,
                        "structuredContent": {
                          "error": {
                            "code": "invalid_params",
                            "message": "Missing required parameter: message_id"
                          }
                        }
                      }
                    }
                  },
                  "propose-send-result": {
                    "summary": "A proposal filed (`propose_send`) — nothing executed; the human confirms at `confirm_url`",
                    "value": {
                      "jsonrpc": "2.0",
                      "id": 6,
                      "result": {
                        "content": [
                          {
                            "type": "text",
                            "text": "{\n  \"intent_id\": \"6d1f0c2e-5555-6666-7777-888888888888\",\n  \"status\": \"proposed\",\n  \"created\": true\n}"
                          }
                        ],
                        "isError": false,
                        "structuredContent": {
                          "intent_id": "6d1f0c2e-5555-6666-7777-888888888888",
                          "workspace_id": "0b7a4c2d-1111-4222-8333-444455556666",
                          "status": "proposed",
                          "expires_at": "2026-09-14T00:15:00Z",
                          "identity_hash": "9f86d081884c7d65",
                          "confirm_url": "https://app.yieldfabric.com/private?reader=intent/0b7a4c2d-1111-4222-8333-444455556666/6d1f0c2e-5555-6666-7777-888888888888",
                          "created": true
                        }
                      }
                    }
                  },
                  "unknown-tool": {
                    "summary": "A name outside the dispatch set (a REST-only direct write, a REST alias, a typo)",
                    "value": {
                      "jsonrpc": "2.0",
                      "id": 5,
                      "error": {
                        "code": -32602,
                        "message": "Unknown tool: yieldfabric_instant"
                      }
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "A notification (request without `id`) was accepted. Empty body."
          },
          "400": {
            "description": "Unsupported `MCP-Protocol-Version` header; the body lists the supported revisions."
          },
          "401": {
            "description": "No bearer, an invalid one, a token minted for another resource, or\na non-connector session. Carries `WWW-Authenticate: Bearer\nresource_metadata=\"…/.well-known/oauth-protected-resource\",\nerror=\"invalid_token\"` and `{\"error\": \"<reason>\"}`.\n"
          },
          "403": {
            "description": "A browser `Origin` header that is not allow-listed."
          },
          "503": {
            "description": "The auth service could not be reached, timed out or failed while\nthe bearer was being exchanged or validated: the credential was\nnot judged. `Retry-After: 5`, `{\"error\": \"Auth service\nunavailable: …\"}`, and NO `WWW-Authenticate` challenge — retry\nthe request; do not re-run the OAuth flow.\n"
          }
        },
        "x-codeSamples": [
          {
            "lang": "curl",
            "label": "curl",
            "source": "curl -s -X POST https://pay.test.yieldfabric.com/mcp \\\n  -H \"Authorization: Bearer $YF_CONNECTOR_API_KEY\" -H 'Content-Type: application/json' \\\n  -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"tools/call\",\"params\":{\"name\":\"whoami\",\"arguments\":{}}}'"
          }
        ]
      },
      "get": {
        "operationId": "mcpGet",
        "summary": "Not available — stateless server",
        "description": "There is no server-push stream (`Mcp-Session-Id` is never issued);\nevery `GET /mcp` is `405 Method Not Allowed`.\n",
        "tags": [
          "MCP"
        ],
        "responses": {
          "405": {
            "description": "Method not allowed."
          }
        }
      }
    },
    "/.well-known/oauth-protected-resource": {
      "get": {
        "operationId": "mcpProtectedResourceMetadata",
        "summary": "RFC 9728 protected-resource metadata for /mcp",
        "description": "Anonymous. Names the authorization server (auth's public origin) that\nguards `/mcp`; the `WWW-Authenticate` challenge on `401` points\nhere. Also served at `/.well-known/oauth-protected-resource/mcp`\n(the RFC 9728 §3.1 path-suffixed form clients derive by inserting the\nwell-known segment before the resource path).\n",
        "tags": [
          "MCP"
        ],
        "responses": {
          "200": {
            "description": "The metadata document.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "resource": {
                      "type": "string",
                      "example": "https://pay.test.yieldfabric.com/mcp"
                    },
                    "authorization_servers": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "example": [
                        "https://auth.yieldfabric.com"
                      ]
                    },
                    "bearer_methods_supported": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "example": [
                        "header"
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/oauth-protected-resource/mcp": {
      "get": {
        "operationId": "mcpProtectedResourceMetadataSuffixed",
        "summary": "RFC 9728 path-suffixed form of the protected-resource metadata",
        "description": "Identical to `/.well-known/oauth-protected-resource`.",
        "tags": [
          "MCP"
        ],
        "responses": {
          "200": {
            "description": "The metadata document."
          }
        }
      }
    },
    "/.well-known/oauth-authorization-server": {
      "get": {
        "operationId": "mcpAuthorizationServerMetadataShim",
        "summary": "Authorization-server metadata shim (pre-RFC-9728 clients)",
        "description": "Anonymous. For MCP clients on the 2025-03-26 discovery flow, which\nprobe the RESOURCE server's origin for RFC 8414 metadata. Fully\nderivable from the auth public URL, so the same document auth serves\nis emitted here (`issuer`, `authorization_endpoint`, `token_endpoint`,\n`registration_endpoint`, PKCE `S256`, grants `authorization_code` +\n`refresh_token`, scope `mcp`). Also served at\n`/.well-known/oauth-authorization-server/mcp`.\n",
        "tags": [
          "MCP"
        ],
        "responses": {
          "200": {
            "description": "The RFC 8414 document."
          }
        }
      }
    },
    "/.well-known/oauth-authorization-server/mcp": {
      "get": {
        "operationId": "mcpAuthorizationServerMetadataShimSuffixed",
        "summary": "Path-suffixed form of the authorization-server metadata shim",
        "description": "Identical to `/.well-known/oauth-authorization-server`.",
        "tags": [
          "MCP"
        ],
        "responses": {
          "200": {
            "description": "The RFC 8414 document."
          }
        }
      }
    },
    "/api/mcp/tools/list": {
      "get": {
        "operationId": "mcpRestListTools",
        "summary": "Bespoke REST — the tool catalog under its historical slash names",
        "description": "Every registry entry (26: the 19 historical tools, `whoami` and\n`wait_for_settlement`, and the five R2 tools `propose_send`,\n`propose_accept`, `propose_swap_credit_for_cash`,\n`propose_complete_swap`, `intent_status` — the last five under their\npublic names, they have no slash alias), each as `{name, description,\ninputSchema}` named by its slash alias (`yieldfabric/list_assets`,\n`yieldfabric/whoami`, …). The `inputSchema` of ten tools was\ncorrected to the arguments the handlers actually read\n(`accept_payment {payment_id}`, `swap_credit_for_cash {denomination,\namount, obligor, deadline?}`, `create_connection_request\n{recipient_id}`, `accept_connection {request_id | invitation_token}`,\n`send_invitation {email, message?, expires_in_hours?}`,\n`list_connection_requests {status?}`, `pipeline/describe_task` and\n`pipeline/find_predecessors {task_name}`, `pipeline/propose {steps}`,\n`agreement/* {deal_id}`). Any validated JWT — except an RFC 8693\non-behalf-of token minted for another callee (see\n`/api/mcp/tools/call`), which is `401` here too.\n",
        "tags": [
          "MCP"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "`{tools: [{name, description, inputSchema}]}`"
          },
          "401": {
            "description": "Missing, malformed, expired, or wrong-audience bearer JWT. Applies to\nboth user tokens (validated by calling auth's `/protected/jwt`) and\nservice tokens (validated locally against the shared `JWT_SECRET`).\n",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "error"
                  ],
                  "properties": {
                    "error": {
                      "type": "object",
                      "required": [
                        "code",
                        "message"
                      ],
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                          "enum": [
                            "BAD_REQUEST",
                            "UNAUTHORIZED",
                            "FORBIDDEN",
                            "CHAIN_ACCOUNT_REQUIRED",
                            "CHAIN_MODE_MISMATCH",
                            "NOT_FOUND",
                            "IDEMPOTENCY_CONFLICT",
                            "SUBMISSION_OUTCOME_UNKNOWN",
                            "INSUFFICIENT_BALANCE",
                            "CONTRACT_STATE_INVALID",
                            "SWAP_STATE_INVALID",
                            "DEAL_STATE_INVALID",
                            "COUNTERPART_NOT_FOUND",
                            "ORACLE_FAILED",
                            "SIGNATURE_INVALID",
                            "DEADLINE_PASSED",
                            "RATE_LIMITED",
                            "INTERNAL_ERROR"
                          ]
                        },
                        "message": {
                          "type": "string"
                        },
                        "details": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "object",
                              "additionalProperties": true
                            },
                            {
                              "type": "null"
                            }
                          ]
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "no-token": {
                    "summary": "Missing Authorization header",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "missing bearer token"
                      }
                    }
                  },
                  "wrong-audience-user": {
                    "summary": "User JWT aud does not include payments",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token audience does not include 'payments' or 'default'"
                      }
                    }
                  },
                  "wrong-audience-service": {
                    "summary": "Service JWT presented with the wrong scoped audience",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "service token audience must be 'payments-service'"
                      }
                    }
                  },
                  "expired": {
                    "summary": "JWT exp in the past",
                    "value": {
                      "error": {
                        "code": "UNAUTHORIZED",
                        "message": "token expired"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/mcp/tools/call": {
      "post": {
        "operationId": "mcpRestCallTool",
        "summary": "Bespoke REST — execute one tool by slash name or public name",
        "description": "`{name, arguments}`. Resolves the public name or the slash alias,\nregardless of release (the REST surface is not release-gated, so the\ndirect writes remain reachable here). Runs under the caller's own\nJWT; `personal`, `mcp_signer`, `delegated` and service sessions have\nit forwarded downstream as before, while a `connector` session's\ntools mint on-behalf-of tokens per callee exactly as on `POST /mcp`\n(its bearer never leaves this process; without a usable\n`JWT_SECRET` such a call is `503 obo_unavailable`). Bodies are unchanged: success is `200\n{content: [{type: text, text: <pretty JSON>}], is_error: false}`\n(the `is_error` key is omitted by the asset, contact and identity-write\ntools, as it always was); a GraphQL/business failure is `200\n{content: [{type: text, text: \"Error: …\"}], is_error: true}`;\nparameter errors are `400 {\"error\": …}`, not-found `404`, an existing\nconnection request `409`, a downstream failure `500`, and unknown\nnames `404 {\"error\": \"Unknown tool: …\"}`. Wrong-chain sessions are\n`409 {error, code: CHAIN_MODE_MISMATCH}`. The agreement tools now\nreach the agents subgraph over HTTP (they were dead through the\nin-process executor) and return `{deal_id, agreement}`,\n`{deal_id, graph}`, `{deal_id, next_payment}`.\n\n**Connector sessions cannot run the direct writes**:\nwith a `session_kind: connector` bearer, the seven direct writes\n(`yieldfabric/send_instant_payment`, `yieldfabric/accept_payment`,\n`yieldfabric/swap_credit_for_cash`, `yieldfabric/complete_swap`,\n`yieldfabric/create_connection_request`,\n`yieldfabric/accept_connection`, `yieldfabric/send_invitation`) answer\n`403 {\"error\": \"FORBIDDEN: connector credentials can only propose …\"}`\nbefore the handler runs — the same guard `POST /graphql` applies to\nmutations (`code: connector_read_only`). Every other session kind\n(`personal`, `mcp_signer`, `delegated`, service) runs them as before.\nThe five R2 tools (`propose_send`, `propose_accept`,\n`propose_swap_credit_for_cash`, `propose_complete_swap`,\n`intent_status`) are reachable here too, under their public names.\n\n**On-behalf-of tokens are accepted only by their callee**: an RFC 8693 exchanged token (`act` present) whose `aud` does\nnot name THIS instance — e.g. the 60-second token this service minted\nFOR agents — is `401` with `WWW-Authenticate: Bearer\nerror=\"invalid_token\", …` and `{\"error\", \"code\": \"wrong_audience\"}`,\ndecided locally under `JWT_SECRET` before auth is asked (fail closed\nwithout a usable secret). The same refusal applies on every REST\nroute of the payments binary (`handlers/connector_guard.rs`), not\nonly `/graphql`.\n\n**Connector sessions never execute anywhere on this binary**: beyond\nthe guard above, a router-wide middleware answers every non-read\nrequest (anything but `GET` / `HEAD` / `OPTIONS`) from a\n`session_kind: connector` bearer with `403 {\"error\": \"FORBIDDEN: …\",\n\"code\": \"connector_read_only\"}` — the workflow starters\n(`/api/asset_register/*_workflow`, `/api/onramp/workflow`), message\n`retry` / `cancel` / `sign`, execution-mode preferences, `/auctions`,\n`/asset_register`, `/claims_management`, `/transfer` … — with\n`/graphql`, `/mcp` and this route keeping their own guards (reads and\nproposals allowed) and the POST-shaped reads (`/api/mcp/initialize`,\n`/api/mcp/prompts/get`, `/market/quotes`, `/api/actions/extract`)\nexempt.\n",
        "tags": [
          "MCP"
        ],
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "name",
                  "arguments"
                ],
                "properties": {
                  "name": {
                    "type": "string",
                    "example": "yieldfabric/list_contacts"
                  },
                  "arguments": {
                    "type": "object"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "`{content: [{type, text}], is_error?}`"
          },
          "400": {
            "description": "Missing or malformed argument — `{\"error\": \"Missing required parameter: <name>\"}`."
          },
          "401": {
            "description": "Missing / invalid bearer (`{\"error\"}`), or an on-behalf-of token minted for another callee (`{\"error\", \"code\": \"wrong_audience\"}` + `WWW-Authenticate`)."
          },
          "403": {
            "description": "A connector session calling a direct write (`FORBIDDEN …`, the `connector_read_only` rule); or agents refusing a proposal for this session."
          },
          "404": {
            "description": "Unknown tool, or the addressed record does not exist."
          },
          "409": {
            "description": "Wrong-chain session (`CHAIN_MODE_MISMATCH`), a walletless session proposing (`CHAIN_ACCOUNT_REQUIRED`), an existing connection request, or an intent conflict reported by agents."
          },
          "500": {
            "description": "A downstream (store, auth, agents) failed."
          }
        }
      }
    },
    "/health": {
      "get": {
        "operationId": "getHealth",
        "summary": "Process liveness",
        "description": "Returns 200 while the HTTP process is running. Use /ready to check\nMQ processing readiness during dependency recovery.\n",
        "tags": [
          "Queries"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "HTTP process is alive.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "status",
                    "timestamp"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "healthy"
                      ]
                    },
                    "timestamp": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/ready": {
      "get": {
        "operationId": "getReadiness",
        "summary": "MQ processing readiness",
        "description": "Returns 200 when MQ dispatch and graph consumption are available,\nor 503 while their runtime is unavailable or recovering. The response\ncontains only status and timestamp. No authentication is required.\nUse /health for process liveness.\n",
        "tags": [
          "Queries"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "MQ processing runtime is ready.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "status",
                    "timestamp"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "ready"
                      ]
                    },
                    "timestamp": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "MQ processing runtime is unavailable or recovering.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "status",
                    "timestamp"
                  ],
                  "properties": {
                    "status": {
                      "type": "string",
                      "enum": [
                        "not_ready"
                      ]
                    },
                    "timestamp": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/version": {
      "get": {
        "operationId": "getVersion",
        "summary": "Build/version identity",
        "description": "Returns the running build's identity (`service`, `api_version`,\n`git_sha`, `built_at`). `api_version` is baked from this spec's\n`info.version` at compile time, so a deployment cannot report a\nversion it doesn't implement — confirm which API contract a\nserver serves without probing routes. No auth required.\n",
        "tags": [
          "Queries"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Build identity of the running service.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "service",
                    "api_version",
                    "git_sha",
                    "built_at"
                  ],
                  "properties": {
                    "service": {
                      "type": "string",
                      "example": "yieldfabric-payments"
                    },
                    "api_version": {
                      "type": "string",
                      "example": "1.0.0"
                    },
                    "git_sha": {
                      "type": "string",
                      "example": "e45bea7b3a30"
                    },
                    "built_at": {
                      "type": "string",
                      "example": "2026-06-14T10:42:33Z"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "HS256-signed JWT in the `Authorization: Bearer <jwt>` header.\nHeader carries `kid: \"v1\"` — one signing secret today; the kid\nstamp is in place so a future multi-key validator can route by it\nwithout re-minting existing tokens.\n\nTwo flavors:\n\n- **User tokens** — minted by `yieldfabric-auth` for human callers\n  (login, refresh, delegation).\n- **Service tokens** — minted by sister services for inter-service\n  REST calls. `sub = \"service:<name>\"`, audience\n  `[\"payments-service\"]`.\n\nService tokens validate locally against a shared `JWT_SECRET`; user\ntokens validate via a round-trip to auth. See\n[architecture/jwt-validation.md](../../architecture/jwt-validation.md)\nfor the routing mechanics.\n\n## Required claims\n\n| Claim | Type | Notes |\n|-------|------|-------|\n| `sub` | string | Entity ID (user_id or group_id) for user tokens; `\"service:<name>\"` for service tokens. |\n| `aud` | string[] | **User tokens**: must include `\"payments\"` or `\"default\"`. Other accepted audiences for adjacent services: `\"yieldfabric\"`, `\"vault\"`. **Service tokens**: `[\"payments-service\"]` only. |\n| `exp` | int (unix) | Expiry. Auth-service default is 15 minutes for access tokens; refresh tokens last 30 days. |\n| `iat` | int (unix) | Issued-at. |\n| `role` | string | UserRole — `SuperAdmin` / `Admin` / `Manager` / `Operator` / `Viewer` / `ApiClient`. |\n| `kind` | object | `{ \"kind\": \"user\" }` for user tokens; `{ \"kind\": \"service\", \"name\": \"<service>\" }` for service tokens. Derived from `sub` at validation time. |\n\n## Optional claims\n\n| Claim | Type | Notes |\n|-------|------|-------|\n| `account_address` | string | Default wallet address on the active chain. |\n| `default_chain_id` | string | Snapshot of the active chain at mint time — sealed for the JWT lifetime. |\n| `default_wallet_id` | string | Default wallet ID on that chain. |\n| `group_account_address` | string | Group's deployed account address; populated on delegation tokens. |\n| `acting_as` | string | **Delegation** — group_id the JWT is acting on behalf of. This is a JWT claim, **not** an HTTP header. |\n| `delegation_scope` | string[] | Operations allowed under delegation. |\n| `delegation_token_id` | string | Audit trail for delegation. |\n\nUser tokens are issued by the `yieldfabric-auth` service. Service\ntokens are minted in-process by auth and never exposed via a public\nendpoint. See [guides/authentication.md](../guides/authentication.md)\nfor the consumer-facing reference.\n"
      },
      "siweAuth": {
        "type": "apiKey",
        "in": "query",
        "name": "auth",
        "description": "**Pseudo-scheme** — SIWE is not an HTTP-level auth scheme for payments.\nThe five `interop_*` operations carry a SIWE message inside the GraphQL\ninput via the `AuthInput` type (`{ claimedAddress, message, signature }`).\nDocumented here for spec completeness only; tooling that consumes this\nscheme should treat it as a marker that the operation has its own\ninner-payload auth, not an actual HTTP credential.\n\nSee [guides/interop.md](../guides/interop.md) and the per-operation files\nunder `operations/interop/`.\n"
      }
    },
    "parameters": {
      "IdempotencyKey": {
        "name": "idempotency_key",
        "in": "query",
        "required": false,
        "description": "Opaque caller-provided string that makes the operation safe to retry.\nSame `idempotency_key` + same request body returns the original response.\nSame `idempotency_key` + different body returns `409 IDEMPOTENCY_CONFLICT`.\nRecommended format: UUIDv4. Suggested TTL: 24 hours.\nSee [guides/idempotency.md](../guides/idempotency.md).\n",
        "schema": {
          "type": "string",
          "format": "uuid"
        }
      },
      "WalletId": {
        "name": "wallet_id",
        "in": "query",
        "required": false,
        "description": "Optional sub-account/wallet selector. When omitted, the operation uses the\nJWT's `default_wallet_id` (or the entity's only wallet if no default is set).\nProvide explicitly to target a specific wallet under the calling entity.\n",
        "schema": {
          "type": "string"
        }
      },
      "RequireManualSignature": {
        "name": "require_manual_signature",
        "in": "query",
        "required": false,
        "description": "When `true`, the operation is queued for user-side manual signing instead of\nbeing signed by the server's keystore. The response will include a pending\nmessage_id; callers poll the Messages REST API (or subscribe to the\nwebsocket) for completion.\n",
        "schema": {
          "type": "boolean",
          "default": false
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Malformed request or invalid field at the HTTP layer (pre-GraphQL).",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "error"
              ],
              "properties": {
                "error": {
                  "type": "object",
                  "required": [
                    "code",
                    "message"
                  ],
                  "properties": {
                    "code": {
                      "type": "string",
                      "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                      "enum": [
                        "BAD_REQUEST",
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "CHAIN_ACCOUNT_REQUIRED",
                        "CHAIN_MODE_MISMATCH",
                        "NOT_FOUND",
                        "IDEMPOTENCY_CONFLICT",
                        "SUBMISSION_OUTCOME_UNKNOWN",
                        "INSUFFICIENT_BALANCE",
                        "CONTRACT_STATE_INVALID",
                        "SWAP_STATE_INVALID",
                        "DEAL_STATE_INVALID",
                        "COUNTERPART_NOT_FOUND",
                        "ORACLE_FAILED",
                        "SIGNATURE_INVALID",
                        "DEADLINE_PASSED",
                        "RATE_LIMITED",
                        "INTERNAL_ERROR"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  }
                }
              }
            },
            "examples": {
              "malformed-json": {
                "summary": "JSON parse error",
                "value": {
                  "error": {
                    "code": "BAD_REQUEST",
                    "message": "request body is not valid JSON"
                  }
                }
              }
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Missing, malformed, expired, or wrong-audience bearer JWT. Applies to\nboth user tokens (validated by calling auth's `/protected/jwt`) and\nservice tokens (validated locally against the shared `JWT_SECRET`).\n",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "error"
              ],
              "properties": {
                "error": {
                  "type": "object",
                  "required": [
                    "code",
                    "message"
                  ],
                  "properties": {
                    "code": {
                      "type": "string",
                      "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                      "enum": [
                        "BAD_REQUEST",
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "CHAIN_ACCOUNT_REQUIRED",
                        "CHAIN_MODE_MISMATCH",
                        "NOT_FOUND",
                        "IDEMPOTENCY_CONFLICT",
                        "SUBMISSION_OUTCOME_UNKNOWN",
                        "INSUFFICIENT_BALANCE",
                        "CONTRACT_STATE_INVALID",
                        "SWAP_STATE_INVALID",
                        "DEAL_STATE_INVALID",
                        "COUNTERPART_NOT_FOUND",
                        "ORACLE_FAILED",
                        "SIGNATURE_INVALID",
                        "DEADLINE_PASSED",
                        "RATE_LIMITED",
                        "INTERNAL_ERROR"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  }
                }
              }
            },
            "examples": {
              "no-token": {
                "summary": "Missing Authorization header",
                "value": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "missing bearer token"
                  }
                }
              },
              "wrong-audience-user": {
                "summary": "User JWT aud does not include payments",
                "value": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "token audience does not include 'payments' or 'default'"
                  }
                }
              },
              "wrong-audience-service": {
                "summary": "Service JWT presented with the wrong scoped audience",
                "value": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "service token audience must be 'payments-service'"
                  }
                }
              },
              "expired": {
                "summary": "JWT exp in the past",
                "value": {
                  "error": {
                    "code": "UNAUTHORIZED",
                    "message": "token expired"
                  }
                }
              }
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found (entity, wallet, payment, contract, swap, deal).",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "error"
              ],
              "properties": {
                "error": {
                  "type": "object",
                  "required": [
                    "code",
                    "message"
                  ],
                  "properties": {
                    "code": {
                      "type": "string",
                      "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                      "enum": [
                        "BAD_REQUEST",
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "CHAIN_ACCOUNT_REQUIRED",
                        "CHAIN_MODE_MISMATCH",
                        "NOT_FOUND",
                        "IDEMPOTENCY_CONFLICT",
                        "SUBMISSION_OUTCOME_UNKNOWN",
                        "INSUFFICIENT_BALANCE",
                        "CONTRACT_STATE_INVALID",
                        "SWAP_STATE_INVALID",
                        "DEAL_STATE_INVALID",
                        "COUNTERPART_NOT_FOUND",
                        "ORACLE_FAILED",
                        "SIGNATURE_INVALID",
                        "DEADLINE_PASSED",
                        "RATE_LIMITED",
                        "INTERNAL_ERROR"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      },
      "IdempotencyConflict": {
        "description": "The supplied `idempotency_key` was previously used with a different request\nbody. The original response is **not** returned — resolve client-side by\nusing a fresh key or replaying the original request.\n",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "error"
              ],
              "properties": {
                "error": {
                  "type": "object",
                  "required": [
                    "code",
                    "message"
                  ],
                  "properties": {
                    "code": {
                      "type": "string",
                      "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                      "enum": [
                        "BAD_REQUEST",
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "CHAIN_ACCOUNT_REQUIRED",
                        "CHAIN_MODE_MISMATCH",
                        "NOT_FOUND",
                        "IDEMPOTENCY_CONFLICT",
                        "SUBMISSION_OUTCOME_UNKNOWN",
                        "INSUFFICIENT_BALANCE",
                        "CONTRACT_STATE_INVALID",
                        "SWAP_STATE_INVALID",
                        "DEAL_STATE_INVALID",
                        "COUNTERPART_NOT_FOUND",
                        "ORACLE_FAILED",
                        "SIGNATURE_INVALID",
                        "DEADLINE_PASSED",
                        "RATE_LIMITED",
                        "INTERNAL_ERROR"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  }
                }
              }
            },
            "examples": {
              "conflict": {
                "summary": "Same key, different body",
                "value": {
                  "error": {
                    "code": "IDEMPOTENCY_CONFLICT",
                    "message": "idempotency_key already used with a different request"
                  }
                }
              }
            }
          }
        }
      },
      "RateLimited": {
        "description": "Reserved for future use. The GraphQL gateway layer does not currently\nenforce rate limits. The auth service applies per-IP progressive delay on\nlogin failures, which can surface here for `interop_*` SIWE auth flows.\n",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "error"
              ],
              "properties": {
                "error": {
                  "type": "object",
                  "required": [
                    "code",
                    "message"
                  ],
                  "properties": {
                    "code": {
                      "type": "string",
                      "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                      "enum": [
                        "BAD_REQUEST",
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "CHAIN_ACCOUNT_REQUIRED",
                        "CHAIN_MODE_MISMATCH",
                        "NOT_FOUND",
                        "IDEMPOTENCY_CONFLICT",
                        "SUBMISSION_OUTCOME_UNKNOWN",
                        "INSUFFICIENT_BALANCE",
                        "CONTRACT_STATE_INVALID",
                        "SWAP_STATE_INVALID",
                        "DEAL_STATE_INVALID",
                        "COUNTERPART_NOT_FOUND",
                        "ORACLE_FAILED",
                        "SIGNATURE_INVALID",
                        "DEADLINE_PASSED",
                        "RATE_LIMITED",
                        "INTERNAL_ERROR"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      },
      "InternalError": {
        "description": "Unexpected server error. Treat as transient; safe to retry with the same idempotency_key.",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "error"
              ],
              "properties": {
                "error": {
                  "type": "object",
                  "required": [
                    "code",
                    "message"
                  ],
                  "properties": {
                    "code": {
                      "type": "string",
                      "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                      "enum": [
                        "BAD_REQUEST",
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "CHAIN_ACCOUNT_REQUIRED",
                        "CHAIN_MODE_MISMATCH",
                        "NOT_FOUND",
                        "IDEMPOTENCY_CONFLICT",
                        "SUBMISSION_OUTCOME_UNKNOWN",
                        "INSUFFICIENT_BALANCE",
                        "CONTRACT_STATE_INVALID",
                        "SWAP_STATE_INVALID",
                        "DEAL_STATE_INVALID",
                        "COUNTERPART_NOT_FOUND",
                        "ORACLE_FAILED",
                        "SIGNATURE_INVALID",
                        "DEADLINE_PASSED",
                        "RATE_LIMITED",
                        "INTERNAL_ERROR"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "details": {
                      "oneOf": [
                        {
                          "type": "string"
                        },
                        {
                          "type": "object",
                          "additionalProperties": true
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        }
      },
      "GraphQLResponse": {
        "description": "Standard GraphQL response envelope. Always HTTP 200 — domain errors are\ninside `errors[]` with structured `extensions.code` values. See\nguides/errors.md for the full code catalogue.\n",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "description": "Standard GraphQL response envelope. The HTTP status is always 200; domain\nerrors are inside `errors[]`.\n",
              "properties": {
                "data": {
                  "type": [
                    "object",
                    "null"
                  ],
                  "additionalProperties": true,
                  "description": "Per-operation payload. Null when there is an unrecoverable error."
                },
                "errors": {
                  "type": [
                    "array",
                    "null"
                  ],
                  "items": {
                    "type": "object",
                    "required": [
                      "message"
                    ],
                    "properties": {
                      "message": {
                        "type": "string"
                      },
                      "path": {
                        "type": "array",
                        "items": {
                          "oneOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "integer"
                            }
                          ]
                        }
                      },
                      "locations": {
                        "type": "array",
                        "items": {
                          "type": "object",
                          "properties": {
                            "line": {
                              "type": "integer"
                            },
                            "column": {
                              "type": "integer"
                            }
                          }
                        }
                      },
                      "extensions": {
                        "type": "object",
                        "properties": {
                          "code": {
                            "type": "string",
                            "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                            "enum": [
                              "BAD_REQUEST",
                              "UNAUTHORIZED",
                              "FORBIDDEN",
                              "CHAIN_ACCOUNT_REQUIRED",
                              "CHAIN_MODE_MISMATCH",
                              "NOT_FOUND",
                              "IDEMPOTENCY_CONFLICT",
                              "SUBMISSION_OUTCOME_UNKNOWN",
                              "INSUFFICIENT_BALANCE",
                              "CONTRACT_STATE_INVALID",
                              "SWAP_STATE_INVALID",
                              "DEAL_STATE_INVALID",
                              "COUNTERPART_NOT_FOUND",
                              "ORACLE_FAILED",
                              "SIGNATURE_INVALID",
                              "DEADLINE_PASSED",
                              "RATE_LIMITED",
                              "INTERNAL_ERROR"
                            ]
                          },
                          "httpStatus": {
                            "type": "integer",
                            "description": "HTTP-equivalent status for a GraphQL domain error."
                          },
                          "chainId": {
                            "type": "string",
                            "description": "Selected chain when the error is chain-qualified."
                          },
                          "entityKind": {
                            "type": "string",
                            "enum": [
                              "user",
                              "group"
                            ]
                          },
                          "entityId": {
                            "type": "string"
                          },
                          "operation": {
                            "type": "string",
                            "description": "Resolver operation that required the missing account."
                          }
                        },
                        "additionalProperties": true
                      }
                    }
                  }
                },
                "extensions": {
                  "type": [
                    "object",
                    "null"
                  ],
                  "additionalProperties": true
                }
              }
            }
          }
        }
      }
    },
    "schemas": {
      "GraphQLRequest": {
        "type": "object",
        "required": [
          "query"
        ],
        "properties": {
          "query": {
            "type": "string",
            "description": "GraphQL operation source (mutation or query, optionally with fragments)."
          },
          "variables": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "Variable bindings for `$var` references in `query`."
          },
          "operationName": {
            "type": [
              "string",
              "null"
            ],
            "description": "When `query` declares multiple operations, names the one to execute."
          }
        },
        "example": {
          "query": "mutation CreateObligation($input: CreateObligationInput!) {\n  createObligation(input: $input) {\n    success\n    contract_id\n    transaction_id\n  }\n}\n",
          "variables": {
            "input": {
              "counterpart": "alice@yieldfabric",
              "denomination": "USD",
              "obligor": "bob@yieldfabric",
              "expiry": "1735603200"
            }
          }
        }
      },
      "GraphQLResponse": {
        "type": "object",
        "description": "Standard GraphQL response envelope. The HTTP status is always 200; domain\nerrors are inside `errors[]`.\n",
        "properties": {
          "data": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true,
            "description": "Per-operation payload. Null when there is an unrecoverable error."
          },
          "errors": {
            "type": [
              "array",
              "null"
            ],
            "items": {
              "type": "object",
              "required": [
                "message"
              ],
              "properties": {
                "message": {
                  "type": "string"
                },
                "path": {
                  "type": "array",
                  "items": {
                    "oneOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "integer"
                      }
                    ]
                  }
                },
                "locations": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "line": {
                        "type": "integer"
                      },
                      "column": {
                        "type": "integer"
                      }
                    }
                  }
                },
                "extensions": {
                  "type": "object",
                  "properties": {
                    "code": {
                      "type": "string",
                      "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                      "enum": [
                        "BAD_REQUEST",
                        "UNAUTHORIZED",
                        "FORBIDDEN",
                        "CHAIN_ACCOUNT_REQUIRED",
                        "CHAIN_MODE_MISMATCH",
                        "NOT_FOUND",
                        "IDEMPOTENCY_CONFLICT",
                        "SUBMISSION_OUTCOME_UNKNOWN",
                        "INSUFFICIENT_BALANCE",
                        "CONTRACT_STATE_INVALID",
                        "SWAP_STATE_INVALID",
                        "DEAL_STATE_INVALID",
                        "COUNTERPART_NOT_FOUND",
                        "ORACLE_FAILED",
                        "SIGNATURE_INVALID",
                        "DEADLINE_PASSED",
                        "RATE_LIMITED",
                        "INTERNAL_ERROR"
                      ]
                    },
                    "httpStatus": {
                      "type": "integer",
                      "description": "HTTP-equivalent status for a GraphQL domain error."
                    },
                    "chainId": {
                      "type": "string",
                      "description": "Selected chain when the error is chain-qualified."
                    },
                    "entityKind": {
                      "type": "string",
                      "enum": [
                        "user",
                        "group"
                      ]
                    },
                    "entityId": {
                      "type": "string"
                    },
                    "operation": {
                      "type": "string",
                      "description": "Resolver operation that required the missing account."
                    }
                  },
                  "additionalProperties": true
                }
              }
            }
          },
          "extensions": {
            "type": [
              "object",
              "null"
            ],
            "additionalProperties": true
          }
        }
      },
      "BaseMutationResponse": {
        "type": "object",
        "required": [
          "success",
          "message",
          "message_id",
          "transaction_id",
          "signature",
          "timestamp"
        ],
        "properties": {
          "success": {
            "type": "boolean",
            "description": "Operation completed end-to-end."
          },
          "message": {
            "type": "string",
            "description": "Human-readable summary."
          },
          "account_address": {
            "type": [
              "string",
              "null"
            ],
            "description": "Wallet address that signed the on-chain side of the operation."
          },
          "message_id": {
            "type": "string",
            "format": "uuid",
            "description": "Message-queue ID for the underlying RabbitMQ workflow step."
          },
          "transaction_id": {
            "type": "string",
            "description": "On-chain transaction hash.",
            "x-onchain": true
          },
          "signature": {
            "type": "string",
            "description": "EIP-191 signature over the message envelope.",
            "x-onchain": true
          },
          "timestamp": {
            "type": "string",
            "format": "date-time",
            "description": "Server-side ISO-8601 timestamp."
          }
        }
      },
      "ErrorBody": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
                "enum": [
                  "BAD_REQUEST",
                  "UNAUTHORIZED",
                  "FORBIDDEN",
                  "CHAIN_ACCOUNT_REQUIRED",
                  "CHAIN_MODE_MISMATCH",
                  "NOT_FOUND",
                  "IDEMPOTENCY_CONFLICT",
                  "SUBMISSION_OUTCOME_UNKNOWN",
                  "INSUFFICIENT_BALANCE",
                  "CONTRACT_STATE_INVALID",
                  "SWAP_STATE_INVALID",
                  "DEAL_STATE_INVALID",
                  "COUNTERPART_NOT_FOUND",
                  "ORACLE_FAILED",
                  "SIGNATURE_INVALID",
                  "DEADLINE_PASSED",
                  "RATE_LIMITED",
                  "INTERNAL_ERROR"
                ]
              },
              "message": {
                "type": "string"
              },
              "details": {
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "object",
                    "additionalProperties": true
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            }
          }
        }
      },
      "ErrorCode": {
        "type": "string",
        "description": "Structured error code returned in `errors[].extensions.code` (GraphQL) or\n`error.code` (HTTP). See [guides/errors.md](../guides/errors.md) for\nthe full catalogue with recovery strategies.\n",
        "enum": [
          "BAD_REQUEST",
          "UNAUTHORIZED",
          "FORBIDDEN",
          "CHAIN_ACCOUNT_REQUIRED",
          "CHAIN_MODE_MISMATCH",
          "NOT_FOUND",
          "IDEMPOTENCY_CONFLICT",
          "SUBMISSION_OUTCOME_UNKNOWN",
          "INSUFFICIENT_BALANCE",
          "CONTRACT_STATE_INVALID",
          "SWAP_STATE_INVALID",
          "DEAL_STATE_INVALID",
          "COUNTERPART_NOT_FOUND",
          "ORACLE_FAILED",
          "SIGNATURE_INVALID",
          "DEADLINE_PASSED",
          "RATE_LIMITED",
          "INTERNAL_ERROR"
        ]
      },
      "PaginationInput": {
        "type": "object",
        "description": "Cursor pagination for list queries.",
        "properties": {
          "cursor": {
            "type": [
              "string",
              "null"
            ],
            "description": "Opaque cursor from the previous page's `pageInfo.endCursor`. Omit for the first page."
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 1000,
            "default": 50
          }
        }
      },
      "PageInfo": {
        "type": "object",
        "required": [
          "hasNextPage"
        ],
        "properties": {
          "endCursor": {
            "type": [
              "string",
              "null"
            ]
          },
          "hasNextPage": {
            "type": "boolean"
          }
        }
      }
    }
  },
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "x-yf-service": "payments"
}