{
  "openapi": "3.1.0",
  "info": {
    "title": "Tesser endpoints exposed to Nexa",
    "version": "v1",
    "description": "Endpoints **Tesser hosts** and **Banco Nexa calls**, for the Tesser x Banco Nexa USDC-to-GTQ offramp POC.\n\nTwo groups:\n\n1. **The webhook receiver** `POST`/`HEAD /v1/webhooks/nexa/{organizationId}`, bespoke for this integration, and the channel for every Nexa decision: credit sent/confirmed, additional funds requested, rejection, and payout failures.\n2. **Two existing Tesser core-API operations** Nexa already needs for treasury: read the USDC balance and withdraw USDC. These are **vendored verbatim** from the live Tesser core API definition so this reference is complete in one place; https://docs.tesser.xyz stays normative, and `bun scripts/vendor-core.ts --check` keeps the copies honest in CI.\n\nAuth (both groups): Nexa presents its client certificate (mTLS). The certificate's SHA-256 fingerprint is registered against Nexa's Tesser API key during onboarding, and Tesser resolves Nexa's identity from it. This is the platform's existing banking-partner mTLS design, nothing new to build. The webhook receiver **additionally** requires the resolved identity to match the `{organizationId}` in the path; a mismatch is a 401. Nexa's webhook deliveries are expected to present the same client certificate.\n\nWebhook delivery is **at-least-once and unordered**: Tesser dedupes on `event_id`, and applies the quote state machine's reachability rule to the `quote_status` an event carries: forward-reachable states are applied, the current state or an ancestor changes nothing, and a conflicting branch or terminal is acked and raises an ops alert rather than being silently dropped. Any 2xx is success; anything else is retried.\n\nMoney amounts are JSON strings, decimal, no exponent notation (`^[0-9]+(\\.[0-9]+)?$`): GTQ at most 2 decimal places, USDC at most 6. Never JSON numbers. Timestamps are RFC 3339 UTC.\n\nThe stub server returns this document's own canonical examples."
  },
  "servers": [
    {
      "url": "https://nexa-poc-main-c82e5ac.zuplo.app/tesser",
      "description": "Tesser-hosted stub of this API (POC)."
    }
  ],
  "tags": [
    {
      "name": "Webhooks",
      "description": "Tesser's receiver for Nexa's events (§7). Matches Tesser's existing partner-webhook convention: `/v1/webhooks/circle/{organizationId}`, `/v1/webhooks/openfx/{workspaceId}`, and so on, all POST plus HEAD."
    },
    {
      "name": "Accounts",
      "description": "Existing Tesser core API (§9.1), vendored. Nexa reads its USDC wallet balance here; balances are the `assets[]` entries on the account, and the wallet's account ID is shared during onboarding (single-wallet MVP). The example below is the core API's own, a fiat bank account; a wallet account additionally carries `crypto_wallet_address` and the `assets[]` array with the USDC `available_balance`."
    },
    {
      "name": "Treasury",
      "description": "Existing Tesser core API (§9.2), vendored. Nexa withdraws USDC here; BitGo converts USDC to USD and pays out (out of scope). Status progression arrives on Tesser's standard withdrawal webhooks, delivered to Nexa's own receiver."
    }
  ],
  "paths": {
    "/v1/webhooks/nexa/{organizationId}": {
      "post": {
        "operationId": "receiveNexaWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Receive Nexa webhook (op 4)",
        "description": "Tesser's receiver for every Nexa-to-Tesser event (§7): the credit decision, additional-funds requests, rejections, and payout failures.\n\n**There is no payout success event.** `POST /v1/payments` is synchronous and carries the outcome — `COMPLETED`, or `FAILED` on a synchronous decline — in its own response, so a `payment.status.changed` event is sent only when a failure (FAILED or RETURNED) surfaces on the rail after a `COMPLETED` response.\n\nThe body is the Nexa-minted envelope `{event_id, event_type, occurred_at, data}`; `data` varies by `event_type`; every shape is in the examples below. Tesser dedupes on `event_id`, so a redelivery is safe. Non-state-advancing events (`quote.additional_funds_requested`, metadata-only `payment.status.changed`) are still processed, on the first delivery of each `event_id`: the reachability rule governs only the `quote_status` field, never whether the event's content is handled.",
        "parameters": [
          {
            "name": "organizationId",
            "in": "path",
            "required": true,
            "description": "Nexa's Tesser organization ID, shared during onboarding. Tesser's existing partner receivers use the organization's UUID; the POC stub accepts any opaque identifier (the portal examples use `org_nexa_001`). The mTLS-resolved identity must match this value.",
            "schema": {
              "type": "string"
            },
            "example": "org_nexa_001"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebhookEnvelope"
              },
              "examples": {
                "quote.credit.sent": {
                  "summary": "quote.credit.sent: Nexa decided to credit; instruction submitted to core banking",
                  "value": {
                    "event_id": "f31c9a4e-0000-4000-8000-000000000001",
                    "event_type": "quote.credit.sent",
                    "occurred_at": "2026-10-14T15:30:00Z",
                    "data": {
                      "tesser_quote_id": "9b2f6c1e-0000-4000-8000-000000000001",
                      "quote_status": "CREDIT_SENT",
                      "gtq_amount": "250000.00"
                    }
                  }
                },
                "quote.credit.confirmed": {
                  "summary": "quote.credit.confirmed: GTQ available in the customer's Nexa account; gtq_amount is authoritative",
                  "value": {
                    "event_id": "f31c9a4e-0000-4000-8000-000000000002",
                    "event_type": "quote.credit.confirmed",
                    "occurred_at": "2026-10-14T15:30:02Z",
                    "data": {
                      "tesser_quote_id": "9b2f6c1e-0000-4000-8000-000000000001",
                      "quote_status": "CREDIT_CONFIRMED",
                      "gtq_amount": "250000.00",
                      "credited_at": "2026-10-14T15:30:02Z"
                    }
                  }
                },
                "quote.additional_funds_requested": {
                  "summary": "quote.additional_funds_requested: Nexa wants more USDC before crediting; the quote stays DEPOSIT_REPORTED",
                  "value": {
                    "event_id": "f31c9a4e-0000-4000-8000-000000000003",
                    "event_type": "quote.additional_funds_requested",
                    "occurred_at": "2026-10-14T15:35:00Z",
                    "data": {
                      "tesser_quote_id": "9b2f6c1e-0000-4000-8000-000000000001",
                      "quote_status": "DEPOSIT_REPORTED",
                      "usdc_total_reported": "32278.480000",
                      "usdc_additional_requested": "500.000000",
                      "note": "Counterparty review on this deposit requires additional collateral before we credit; send it to the same custody address and we will credit the full quote."
                    }
                  }
                },
                "quote.rejected": {
                  "summary": "quote.rejected: Nexa declines to credit. Not an undo: the USDC already moved on-chain (disposition is out-of-band, §11 Q4)",
                  "value": {
                    "event_id": "f31c9a4e-0000-4000-8000-000000000004",
                    "event_type": "quote.rejected",
                    "occurred_at": "2026-10-14T15:40:00Z",
                    "data": {
                      "tesser_quote_id": "9b2f6c1e-0000-4000-8000-000000000001",
                      "quote_status": "REJECTED",
                      "reason_code": "RISK",
                      "note": "Compliance review of the originating counterparty did not clear."
                    }
                  }
                },
                "payment.status.changed": {
                  "summary": "payment.status.changed: the payout FAILED on the rail after a COMPLETED response (the only payout event; RETURNED is the alternative outcome)",
                  "value": {
                    "event_id": "f31c9a4e-0000-4000-8000-000000000005",
                    "event_type": "payment.status.changed",
                    "occurred_at": "2026-10-14T16:12:44Z",
                    "data": {
                      "tesser_quote_id": "9b2f6c1e-0000-4000-8000-000000000001",
                      "nexa_payment_id": "NXP-2026-000112",
                      "payment_status": "FAILED",
                      "quote_status": "PAYMENT_FAILED",
                      "status_metadata": {
                        "rail_reference": "NXR-2026-884412",
                        "failure_reason": "Beneficiary account rejected the credit."
                      }
                    }
                  }
                },
                "payment.status.changed.returned": {
                  "summary": "payment.status.changed: the payout was RETURNED by the rail after a COMPLETED response (the only payout event; FAILED is the alternative outcome)",
                  "value": {
                    "event_id": "f31c9a4e-0000-4000-8000-000000000006",
                    "event_type": "payment.status.changed",
                    "occurred_at": "2026-10-14T18:40:02Z",
                    "data": {
                      "tesser_quote_id": "9b2f6c1e-0000-4000-8000-000000000001",
                      "nexa_payment_id": "NXP-2026-000112",
                      "payment_status": "RETURNED",
                      "quote_status": "PAYMENT_RETURNED",
                      "status_metadata": {
                        "rail_reference": "NXR-2026-884412",
                        "failure_reason": "Funds returned by the receiving institution."
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Delivery accepted. Nexa treats any 2xx as success; a production receiver may return a truly empty body, and the empty object below is the explicit contract this document specifies so every operation has a schema and an example. A 200 means 'received and deduped', not 'the event was reachable'. An unreachable event is also acked (and alerted on internally).",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                },
                "examples": {
                  "default": {
                    "summary": "Empty acknowledgement",
                    "value": {}
                  }
                }
              }
            }
          },
          "400": {
            "description": "Request failed validation.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "examples": {
                  "default": {
                    "summary": "VALIDATION_ERROR",
                    "value": {
                      "errors": [
                        {
                          "error_code": "VALIDATION_ERROR",
                          "error_message": "Webhook envelope is missing required fields."
                        }
                      ],
                      "request_id": "req_01JA7Q2W3E4R5T6Y7U8I9O0P"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthenticated. Either the client certificate is not recognised, or (the case specific to this operation) the identity Tesser resolved from the certificate does not match the organizationId in the path. Retrying will not help: correct the URL or the certificate.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "examples": {
                  "default": {
                    "summary": "UNAUTHENTICATED: identity does not match organizationId",
                    "value": {
                      "errors": [
                        {
                          "error_code": "UNAUTHENTICATED",
                          "error_message": "The client certificate resolves to a different organization than the organizationId in the path."
                        }
                      ],
                      "request_id": "req_01JA7Q2W3E4R5T6Y7U8I9O0P"
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Unexpected error on Tesser's side. Nexa should retry with backoff; the delivery is not acknowledged.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorEnvelope"
                },
                "examples": {
                  "default": {
                    "summary": "INTERNAL_ERROR",
                    "value": {
                      "errors": [
                        {
                          "error_code": "INTERNAL_ERROR",
                          "error_message": "Unexpected error. Retry the delivery; quote the request_id to Tesser support if it persists."
                        }
                      ],
                      "request_id": "req_01JA7Q2W3E4R5T6Y7U8I9O0P"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "head": {
        "operationId": "verifyNexaWebhook",
        "tags": [
          "Webhooks"
        ],
        "summary": "Verify webhook connectivity (op 4)",
        "description": "Connectivity and credential check for the receiver above, per Tesser's existing partner-webhook convention (every partner receiver is POST plus HEAD). Nexa can call it at onboarding and after certificate rotation to confirm the endpoint is reachable and its client certificate resolves to `{organizationId}`.\n\nA HEAD response carries no body, so the §5 error envelope does not apply here and the status code alone is the answer. `400` is not listed because there is no request body to validate.",
        "parameters": [
          {
            "name": "organizationId",
            "in": "path",
            "required": true,
            "description": "Nexa's Tesser organization ID, shared during onboarding, the same value as on the POST.",
            "schema": {
              "type": "string"
            },
            "example": "org_nexa_001"
          }
        ],
        "responses": {
          "200": {
            "description": "The receiver is reachable and the client certificate resolves to this organizationId. No body."
          },
          "401": {
            "description": "The client certificate is not recognised, or it resolves to a different organization than the organizationId in the path. No body."
          },
          "500": {
            "description": "Unexpected error on Tesser's side. No body."
          }
        }
      }
    },
    "/v1/accounts/{id}": {
      "get": {
        "description": "Retrieve a specific account by its unique identifier.",
        "operationId": "account_findOne",
        "parameters": [
          {
            "name": "id",
            "required": true,
            "in": "path",
            "description": "Account ID (UUID)",
            "schema": {
              "example": "8f3b1e7c-9a2d-4f58-b6c0-4e7d2a9f1b3c",
              "type": "string"
            }
          },
          {
            "name": "include_secure",
            "required": false,
            "in": "query",
            "description": "Include masked secure fields (e.g., bank account number)",
            "schema": {
              "type": "boolean"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Account retrieved successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AccountResponseDto"
                },
                "examples": {
                  "default": {
                    "value": {
                      "data": {
                        "id": "8f3b1e7c-9a2d-4f58-b6c0-4e7d2a9f1b3c",
                        "workspace_id": "b53f6690-3242-4942-9907-885779632832",
                        "tenant_id": null,
                        "counterparty_id": "2a7e1c9f-4b3d-4a82-b6e0-8f5c2d1a9b3e",
                        "type": "fiat_bank",
                        "name": "Operating Account - EU",
                        "bank_name": "Chase Bank",
                        "bank_code_type": "SWIFT",
                        "bank_identifier_code": "CHASUS33",
                        "created_at": "2024-03-02T14:30:00.000Z",
                        "updated_at": "2024-03-02T14:30:00.000Z",
                        "bank_account_number": "•••6789",
                        "created_by": "CUSTOMER"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request data",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "error_code": {
                            "type": "string"
                          },
                          "error_message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "error_code",
                          "error_message"
                        ]
                      }
                    },
                    "request_id": {
                      "type": "string",
                      "description": "Correlation id for this request. Include it when reporting an issue so support can locate the logs."
                    }
                  },
                  "required": [
                    "errors"
                  ],
                  "example": {
                    "errors": [
                      {
                        "error_code": "counterparties-3001",
                        "error_message": "classification must be one of: individual, business"
                      },
                      {
                        "error_code": "counterparties-3002",
                        "error_message": "business_legal_name is required when classification is business"
                      }
                    ]
                  }
                },
                "examples": {
                  "default": {
                    "value": {
                      "errors": [
                        {
                          "error_code": "counterparties-3001",
                          "error_message": "classification must be one of: individual, business"
                        },
                        {
                          "error_code": "counterparties-3002",
                          "error_message": "business_legal_name is required when classification is business"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication required or invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "error_code": {
                            "type": "string"
                          },
                          "error_message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "error_code",
                          "error_message"
                        ]
                      }
                    },
                    "request_id": {
                      "type": "string",
                      "description": "Correlation id for this request. Include it when reporting an issue so support can locate the logs."
                    }
                  },
                  "required": [
                    "errors"
                  ],
                  "example": {
                    "errors": [
                      {
                        "error_code": "api-0004",
                        "error_message": "Unauthorized"
                      }
                    ]
                  }
                },
                "examples": {
                  "default": {
                    "value": {
                      "errors": [
                        {
                          "error_code": "api-0004",
                          "error_message": "Unauthorized"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "error_code": {
                            "type": "string"
                          },
                          "error_message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "error_code",
                          "error_message"
                        ]
                      }
                    },
                    "request_id": {
                      "type": "string",
                      "description": "Correlation id for this request. Include it when reporting an issue so support can locate the logs."
                    }
                  },
                  "required": [
                    "errors"
                  ],
                  "example": {
                    "errors": [
                      {
                        "error_code": "api-0001",
                        "error_message": "Resource not found"
                      }
                    ]
                  }
                },
                "examples": {
                  "default": {
                    "value": {
                      "errors": [
                        {
                          "error_code": "api-0001",
                          "error_message": "Resource not found"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "error_code": {
                            "type": "string"
                          },
                          "error_message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "error_code",
                          "error_message"
                        ]
                      }
                    },
                    "request_id": {
                      "type": "string",
                      "description": "Correlation id for this request. Include it when reporting an issue so support can locate the logs."
                    }
                  },
                  "required": [
                    "errors"
                  ],
                  "example": {
                    "errors": [
                      {
                        "error_code": "api-0006",
                        "error_message": "An unexpected error occurred"
                      }
                    ]
                  }
                },
                "examples": {
                  "default": {
                    "value": {
                      "errors": [
                        {
                          "error_code": "api-0006",
                          "error_message": "An unexpected error occurred"
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "summary": "Get an account by ID",
        "tags": [
          "Accounts"
        ]
      }
    },
    "/v1/treasury/withdrawals": {
      "post": {
        "description": "Create a withdrawal from a managed account or self-custodial wallet to an external bank account.\n\n**Source types:**\n- Circle USDC ledger (path A) — `desired.from.network` omitted.\n- Self-custodial wallet (path B) — `desired.from.network` populated (e.g., `BASE`).",
        "operationId": "treasury_createWithdrawal",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWithdrawalRequest"
              },
              "examples": {
                "default": {
                  "summary": "Withdraw USDC from Circle ledger to USD bank account",
                  "value": {
                    "desired": {
                      "from": {
                        "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
                        "amount": "1000",
                        "currency": "USDC"
                      },
                      "to": {
                        "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
                        "currency": "USD"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Withdrawal created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WithdrawalResponse"
                },
                "examples": {
                  "default": {
                    "value": {
                      "data": {
                        "id": "6a2f8c1e-3b9d-4e74-b5a0-7c4d2e1f9b3a",
                        "workspace_id": "b53f6690-3242-4942-9907-885779632832",
                        "organization_reference_id": null,
                        "direction": "outbound",
                        "desired": {
                          "from": {
                            "account_id": "55042f8f-e527-56f1-b57c-eef23ca862db",
                            "amount": "1000",
                            "currency": "USDC",
                            "network": null
                          },
                          "to": {
                            "account_id": "44031e7e-d416-45f0-a46b-ded12b9751ca",
                            "amount": null,
                            "currency": "USD",
                            "network": null
                          }
                        },
                        "estimated": {
                          "from": {
                            "account_id": null,
                            "amount": null,
                            "currency": null,
                            "network": null
                          },
                          "to": {
                            "account_id": null,
                            "amount": null,
                            "currency": null,
                            "network": null
                          }
                        },
                        "actual": {
                          "from": {
                            "account_id": null,
                            "amount": null,
                            "currency": null,
                            "network": null
                          },
                          "to": {
                            "account_id": null,
                            "amount": null,
                            "currency": null,
                            "network": null
                          }
                        },
                        "balance_status": "unreserved",
                        "balance_reserved_at": null,
                        "steps": [],
                        "created_at": "2024-03-01T10:00:00.000Z",
                        "updated_at": "2024-03-01T10:00:00.000Z",
                        "expires_at": "2024-03-01T14:00:00.000Z"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid request data",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "error_code": {
                            "type": "string"
                          },
                          "error_message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "error_code",
                          "error_message"
                        ]
                      }
                    },
                    "request_id": {
                      "type": "string",
                      "description": "Correlation id for this request. Include it when reporting an issue so support can locate the logs."
                    }
                  },
                  "required": [
                    "errors"
                  ],
                  "example": {
                    "errors": [
                      {
                        "error_code": "counterparties-3001",
                        "error_message": "classification must be one of: individual, business"
                      },
                      {
                        "error_code": "counterparties-3002",
                        "error_message": "business_legal_name is required when classification is business"
                      }
                    ]
                  }
                },
                "examples": {
                  "default": {
                    "value": {
                      "errors": [
                        {
                          "error_code": "counterparties-3001",
                          "error_message": "classification must be one of: individual, business"
                        },
                        {
                          "error_code": "counterparties-3002",
                          "error_message": "business_legal_name is required when classification is business"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Authentication required or invalid credentials",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "error_code": {
                            "type": "string"
                          },
                          "error_message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "error_code",
                          "error_message"
                        ]
                      }
                    },
                    "request_id": {
                      "type": "string",
                      "description": "Correlation id for this request. Include it when reporting an issue so support can locate the logs."
                    }
                  },
                  "required": [
                    "errors"
                  ],
                  "example": {
                    "errors": [
                      {
                        "error_code": "api-0004",
                        "error_message": "Unauthorized"
                      }
                    ]
                  }
                },
                "examples": {
                  "default": {
                    "value": {
                      "errors": [
                        {
                          "error_code": "api-0004",
                          "error_message": "Unauthorized"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Internal server error",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "errors": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "error_code": {
                            "type": "string"
                          },
                          "error_message": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "error_code",
                          "error_message"
                        ]
                      }
                    },
                    "request_id": {
                      "type": "string",
                      "description": "Correlation id for this request. Include it when reporting an issue so support can locate the logs."
                    }
                  },
                  "required": [
                    "errors"
                  ],
                  "example": {
                    "errors": [
                      {
                        "error_code": "api-0006",
                        "error_message": "An unexpected error occurred"
                      }
                    ]
                  }
                },
                "examples": {
                  "default": {
                    "value": {
                      "errors": [
                        {
                          "error_code": "api-0006",
                          "error_message": "An unexpected error occurred"
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "summary": "Create withdrawal",
        "tags": [
          "Treasury"
        ]
      }
    }
  },
  "components": {
    "schemas": {
      "Money": {
        "type": "string",
        "pattern": "^[0-9]+(\\.[0-9]+)?$"
      },
      "QuoteStatus": {
        "type": "string",
        "enum": [
          "CREATED",
          "ACCEPTED",
          "DEPOSIT_REPORTED",
          "CREDIT_SENT",
          "CREDIT_CONFIRMED",
          "PAYMENT_COMPLETED",
          "PAYMENT_FAILED",
          "PAYMENT_RETURNED",
          "EXPIRED",
          "REJECTED"
        ]
      },
      "PaymentStatus": {
        "type": "string",
        "enum": [
          "COMPLETED",
          "FAILED",
          "RETURNED"
        ],
        "description": "Outcome of the payout. The call performs the payout and answers with the outcome, so `COMPLETED` or `FAILED` can both come back synchronously. `RETURNED`, and a `FAILED` that only surfaces on the rail after a `COMPLETED` response, arrive later via the failure webhook."
      },
      "RiskStatus": {
        "type": "string",
        "enum": [
          "unchecked",
          "awaiting_decision",
          "automatically_approved",
          "manually_approved",
          "automatically_rejected",
          "manually_rejected"
        ]
      },
      "RiskStatusReason": {
        "type": "object",
        "properties": {
          "risk_status_reason_type": {
            "type": "string",
            "enum": [
              "ENTITY",
              "ACCOUNT",
              "OWNERSHIP",
              "COUNTERPARTY",
              "INDIRECT",
              "BEHAVIORAL",
              "ERROR"
            ]
          },
          "risk_status_reason_category": {
            "type": "string"
          },
          "risk_status_reason_message": {
            "type": "string"
          }
        },
        "required": [
          "risk_status_reason_type"
        ]
      },
      "ErrorEnvelope": {
        "type": "object",
        "properties": {
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "error_code": {
                  "type": "string"
                },
                "error_message": {
                  "type": "string"
                }
              },
              "required": [
                "error_code",
                "error_message"
              ]
            }
          },
          "request_id": {
            "type": "string"
          }
        },
        "required": [
          "errors",
          "request_id"
        ]
      },
      "WebhookEnvelope": {
        "type": "object",
        "properties": {
          "event_id": {
            "type": "string",
            "format": "uuid"
          },
          "event_type": {
            "type": "string"
          },
          "occurred_at": {
            "type": "string",
            "format": "date-time"
          },
          "data": {
            "type": "object"
          }
        },
        "required": [
          "event_id",
          "event_type",
          "occurred_at",
          "data"
        ]
      },
      "AccountAssetDto": {
        "type": "object",
        "properties": {
          "currency": {
            "type": "string",
            "description": "Currency symbol",
            "example": "USDC"
          },
          "network": {
            "type": "string",
            "description": "Blockchain network (only for wallet accounts)",
            "example": "POLYGON"
          },
          "available_balance": {
            "type": "string",
            "description": "Available balance as a decimal string in currency units. Precision depends on the currency, network, and account provider.",
            "example": "1"
          }
        },
        "required": [
          "currency",
          "available_balance"
        ]
      },
      "AccountData": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique identifier for the account"
          },
          "workspace_id": {
            "type": "string",
            "description": "Workspace ID the account belongs to"
          },
          "tenant_id": {
            "type": "string",
            "nullable": true,
            "description": "Tenant ID (if account belongs to a tenant)"
          },
          "counterparty_id": {
            "type": "string",
            "nullable": true,
            "description": "Counterparty ID (if account belongs to a counterparty)"
          },
          "type": {
            "type": "string",
            "description": "Account type"
          },
          "name": {
            "type": "string",
            "description": "Account name"
          },
          "bank_name": {
            "type": "string",
            "nullable": true,
            "description": "Bank name (only for fiat_bank accounts)"
          },
          "bank_code_type": {
            "type": "string",
            "nullable": true,
            "description": "Bank code type (only for fiat_bank accounts)"
          },
          "bank_identifier_code": {
            "type": "string",
            "nullable": true,
            "description": "Bank identifier code (only for fiat_bank accounts)"
          },
          "bank_swift_code": {
            "type": "string",
            "nullable": true,
            "description": "SWIFT code (only for fiat_bank accounts)"
          },
          "bank_account_number": {
            "type": "string",
            "nullable": true,
            "description": "Bank account number (masked, only with include_secure=true)"
          },
          "crypto_wallet_address": {
            "type": "string",
            "nullable": true,
            "description": "Crypto wallet address (only for wallet accounts)"
          },
          "is_managed": {
            "type": "boolean",
            "nullable": true,
            "description": "Is managed wallet (only for wallet accounts)"
          },
          "generic_account_number": {
            "type": "string",
            "nullable": true,
            "description": "Account identifier (only for generic accounts)"
          },
          "provider": {
            "type": "string",
            "nullable": true,
            "description": "Ledger provider (only for ledger accounts)",
            "enum": [
              "CIRCLE_MINT",
              "KRAKEN",
              "OPENFX",
              "ZUBA"
            ]
          },
          "assets": {
            "description": "Account assets with balances (for wallet and ledger accounts)",
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/AccountAssetDto"
            }
          },
          "created_by": {
            "type": "string",
            "description": "Whether the customer registered this account (CUSTOMER) or Tesser synthesized it (SYSTEM).",
            "enum": [
              "CUSTOMER",
              "SYSTEM"
            ]
          },
          "created_at": {
            "type": "string",
            "description": "Creation timestamp"
          },
          "updated_at": {
            "type": "string",
            "description": "Last update timestamp"
          }
        },
        "required": [
          "id",
          "workspace_id",
          "type",
          "name",
          "created_by",
          "created_at",
          "updated_at"
        ]
      },
      "AccountResponseDto": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/AccountData"
          }
        },
        "required": [
          "data"
        ]
      },
      "CreateWithdrawalRequest": {
        "type": "object",
        "properties": {
          "organization_reference_id": {
            "type": "string",
            "description": "Optional client-supplied identifier."
          },
          "desired": {
            "description": "Caller's stated intent for the withdrawal.",
            "allOf": [
              {
                "$ref": "#/components/schemas/WithdrawalDesiredOverlayRequest"
              }
            ]
          }
        },
        "required": [
          "desired"
        ]
      },
      "StatusReason": {
        "type": "object",
        "properties": {
          "error_code": {
            "type": "string",
            "example": "transfers-9201"
          },
          "error_message": {
            "type": "string",
            "example": "An upstream step failed, so this step was not executed"
          }
        },
        "required": [
          "error_code",
          "error_message"
        ]
      },
      "StepFee": {
        "type": "object",
        "properties": {
          "fee_amount": {
            "type": "string",
            "description": "Fee amount."
          },
          "fee_currency": {
            "type": "string",
            "description": "Fee currency code."
          },
          "fee_type": {
            "type": "string",
            "description": "Fee type (e.g., 'gas', 'provider', 'tesser_fee')."
          },
          "fee_metadata": {
            "type": "object",
            "description": "Additional metadata for the fee (JSON object).",
            "additionalProperties": true
          }
        },
        "required": [
          "fee_amount",
          "fee_currency",
          "fee_type"
        ]
      },
      "Withdrawal": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique withdrawal identifier",
            "example": "6a2f8c1e-3b9d-4e74-b5a0-7c4d2e1f9b3a"
          },
          "workspace_id": {
            "type": "string",
            "description": "Workspace ID the withdrawal belongs to",
            "example": "b53f6690-3242-4942-9907-885779632832"
          },
          "organization_reference_id": {
            "type": "string",
            "description": "External reference ID for tracking",
            "nullable": true,
            "example": null
          },
          "direction": {
            "type": "string",
            "description": "Resource direction.",
            "enum": [
              "outbound"
            ],
            "example": "outbound"
          },
          "desired": {
            "description": "Caller's stated intent at creation. Frozen, never overwritten.",
            "allOf": [
              {
                "$ref": "#/components/schemas/WithdrawalDesiredOverlay"
              }
            ]
          },
          "estimated": {
            "description": "Tesser's projection for how the withdrawal will proceed.",
            "allOf": [
              {
                "$ref": "#/components/schemas/WithdrawalEstimatedOverlay"
              }
            ]
          },
          "actual": {
            "description": "What actually settled. Populated when the withdrawal reaches a terminal state.",
            "allOf": [
              {
                "$ref": "#/components/schemas/WithdrawalActualOverlay"
              }
            ]
          },
          "balance_status": {
            "type": "string",
            "description": "Balance reservation status.",
            "nullable": true,
            "enum": [
              "unreserved",
              "awaiting_funds",
              "reserved"
            ],
            "example": "unreserved"
          },
          "balance_reserved_at": {
            "type": "string",
            "description": "Timestamp when balance was reserved.",
            "format": "date-time",
            "nullable": true,
            "example": null
          },
          "steps": {
            "description": "Withdrawal execution steps.",
            "example": [],
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/WithdrawalStep"
            }
          },
          "created_at": {
            "type": "string",
            "description": "ISO 8601 timestamp of creation.",
            "example": "2024-03-01T10:00:00.000Z"
          },
          "updated_at": {
            "type": "string",
            "description": "ISO 8601 timestamp of last update.",
            "example": "2024-03-01T10:00:00.000Z"
          },
          "expires_at": {
            "type": "string",
            "description": "ISO 8601 timestamp when the withdrawal expires.",
            "example": "2024-03-01T14:00:00.000Z",
            "nullable": true
          }
        },
        "required": [
          "id",
          "workspace_id",
          "direction",
          "desired",
          "estimated",
          "actual",
          "balance_status",
          "balance_reserved_at",
          "steps",
          "created_at",
          "updated_at",
          "expires_at"
        ]
      },
      "WithdrawalActualFromLeg": {
        "type": "object",
        "properties": {
          "account_id": {
            "type": "string",
            "description": "Account ID.",
            "nullable": true
          },
          "amount": {
            "type": "string",
            "description": "Amount.",
            "nullable": true
          },
          "currency": {
            "type": "string",
            "description": "Currency code.",
            "nullable": true
          },
          "network": {
            "type": "string",
            "description": "Blockchain network.",
            "nullable": true
          }
        },
        "description": "Source side.",
        "required": [
          "account_id",
          "amount",
          "currency",
          "network"
        ]
      },
      "WithdrawalActualOverlay": {
        "type": "object",
        "properties": {
          "from": {
            "$ref": "#/components/schemas/WithdrawalActualFromLeg"
          },
          "to": {
            "$ref": "#/components/schemas/WithdrawalActualToLeg"
          }
        },
        "description": "What actually settled. Populated when the withdrawal reaches a terminal state.",
        "required": [
          "from",
          "to"
        ]
      },
      "WithdrawalActualToLeg": {
        "type": "object",
        "properties": {
          "account_id": {
            "type": "string",
            "description": "Account ID.",
            "nullable": true
          },
          "amount": {
            "type": "string",
            "description": "Amount.",
            "nullable": true
          },
          "currency": {
            "type": "string",
            "description": "Currency code.",
            "nullable": true
          },
          "network": {
            "type": "string",
            "description": "Blockchain network.",
            "nullable": true
          }
        },
        "description": "Destination side.",
        "required": [
          "account_id",
          "amount",
          "currency",
          "network"
        ]
      },
      "WithdrawalDesiredFromLeg": {
        "type": "object",
        "properties": {
          "account_id": {
            "type": "string",
            "description": "Source account ID."
          },
          "amount": {
            "type": "string",
            "description": "Source amount.",
            "example": "1000.00"
          },
          "currency": {
            "type": "string",
            "description": "Source currency code.",
            "example": "USDC"
          },
          "network": {
            "type": "string",
            "description": "Source blockchain network. Required when source is a self-custodial wallet."
          }
        },
        "description": "Source side of the withdrawal.",
        "required": [
          "account_id",
          "amount",
          "currency"
        ]
      },
      "WithdrawalDesiredFromLegResponse": {
        "type": "object",
        "properties": {
          "account_id": {
            "type": "string",
            "description": "Account ID.",
            "nullable": true
          },
          "amount": {
            "type": "string",
            "description": "Amount.",
            "nullable": true
          },
          "currency": {
            "type": "string",
            "description": "Currency code.",
            "nullable": true
          },
          "network": {
            "type": "string",
            "description": "Blockchain network.",
            "nullable": true
          }
        },
        "description": "Source side.",
        "required": [
          "account_id",
          "amount",
          "currency",
          "network"
        ]
      },
      "WithdrawalDesiredOverlay": {
        "type": "object",
        "properties": {
          "from": {
            "$ref": "#/components/schemas/WithdrawalDesiredFromLegResponse"
          },
          "to": {
            "$ref": "#/components/schemas/WithdrawalDesiredToLegResponse"
          }
        },
        "description": "Caller's stated intent at creation. Frozen, never overwritten.",
        "required": [
          "from",
          "to"
        ]
      },
      "WithdrawalDesiredOverlayRequest": {
        "type": "object",
        "properties": {
          "from": {
            "description": "Source side of the withdrawal.",
            "allOf": [
              {
                "$ref": "#/components/schemas/WithdrawalDesiredFromLeg"
              }
            ]
          },
          "to": {
            "description": "Destination side of the withdrawal.",
            "allOf": [
              {
                "$ref": "#/components/schemas/WithdrawalDesiredToLeg"
              }
            ]
          }
        },
        "description": "Caller's stated intent for the withdrawal.",
        "required": [
          "from",
          "to"
        ]
      },
      "WithdrawalDesiredToLeg": {
        "type": "object",
        "properties": {
          "account_id": {
            "type": "string",
            "description": "Destination bank account ID."
          },
          "currency": {
            "type": "string",
            "description": "Destination currency code.",
            "example": "USD"
          }
        },
        "description": "Destination side of the withdrawal.",
        "required": [
          "account_id",
          "currency"
        ]
      },
      "WithdrawalDesiredToLegResponse": {
        "type": "object",
        "properties": {
          "account_id": {
            "type": "string",
            "description": "Account ID.",
            "nullable": true
          },
          "amount": {
            "type": "string",
            "description": "Amount.",
            "nullable": true
          },
          "currency": {
            "type": "string",
            "description": "Currency code.",
            "nullable": true
          },
          "network": {
            "type": "string",
            "description": "Blockchain network.",
            "nullable": true
          }
        },
        "description": "Destination side.",
        "required": [
          "account_id",
          "amount",
          "currency",
          "network"
        ]
      },
      "WithdrawalEstimatedFromLeg": {
        "type": "object",
        "properties": {
          "account_id": {
            "type": "string",
            "description": "Account ID.",
            "nullable": true
          },
          "amount": {
            "type": "string",
            "description": "Amount.",
            "nullable": true
          },
          "currency": {
            "type": "string",
            "description": "Currency code.",
            "nullable": true
          },
          "network": {
            "type": "string",
            "description": "Blockchain network.",
            "nullable": true
          }
        },
        "description": "Source side.",
        "required": [
          "account_id",
          "amount",
          "currency",
          "network"
        ]
      },
      "WithdrawalEstimatedOverlay": {
        "type": "object",
        "properties": {
          "from": {
            "$ref": "#/components/schemas/WithdrawalEstimatedFromLeg"
          },
          "to": {
            "$ref": "#/components/schemas/WithdrawalEstimatedToLeg"
          }
        },
        "description": "Tesser's projection for how the withdrawal will proceed.",
        "required": [
          "from",
          "to"
        ]
      },
      "WithdrawalEstimatedToLeg": {
        "type": "object",
        "properties": {
          "account_id": {
            "type": "string",
            "description": "Account ID.",
            "nullable": true
          },
          "amount": {
            "type": "string",
            "description": "Amount.",
            "nullable": true
          },
          "currency": {
            "type": "string",
            "description": "Currency code.",
            "nullable": true
          },
          "network": {
            "type": "string",
            "description": "Blockchain network.",
            "nullable": true
          }
        },
        "description": "Destination side.",
        "required": [
          "account_id",
          "amount",
          "currency",
          "network"
        ]
      },
      "WithdrawalResponse": {
        "type": "object",
        "properties": {
          "data": {
            "description": "Withdrawal data",
            "allOf": [
              {
                "$ref": "#/components/schemas/Withdrawal"
              }
            ]
          }
        },
        "required": [
          "data"
        ]
      },
      "WithdrawalStep": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Unique step identifier",
            "example": "4f7c1a9e-2b3d-4e85-b0a6-8d5c2e1f3b9a"
          },
          "withdrawal_id": {
            "type": "string",
            "description": "ID of the parent withdrawal",
            "example": "6a2f8c1e-3b9d-4e74-b5a0-7c4d2e1f9b3a"
          },
          "step_sequence": {
            "type": "integer",
            "description": "Order of this step in the withdrawal flow (1-based)",
            "example": 1
          },
          "step_type": {
            "type": "string",
            "description": "Type of step",
            "enum": [
              "transfer",
              "swap"
            ],
            "example": "transfer"
          },
          "estimated": {
            "description": "Planned values for this step.",
            "allOf": [
              {
                "$ref": "#/components/schemas/WithdrawalStepEstimatedOverlay"
              }
            ]
          },
          "actual": {
            "description": "Settled values once the step reaches a terminal state. All-null until then.",
            "allOf": [
              {
                "$ref": "#/components/schemas/WithdrawalStepActualOverlay"
              }
            ]
          },
          "transaction_hash": {
            "type": "string",
            "description": "Blockchain transaction hash",
            "nullable": true,
            "example": null
          },
          "unsigned_transaction": {
            "type": "string",
            "description": "Unsigned transaction bytes for client signing. Present only for Turnkey-signed steps in signature_requested status.",
            "nullable": true
          },
          "fees": {
            "description": "Fees associated with this step",
            "example": [],
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StepFee"
            }
          },
          "provider_key": {
            "type": "string",
            "description": "Provider used for this step",
            "nullable": true,
            "enum": [
              "circle_mint",
              "kraken",
              "turnkey",
              "openfx",
              "zuba"
            ],
            "example": "circle_mint"
          },
          "status": {
            "type": "string",
            "description": "Current status of this step",
            "enum": [
              "created",
              "signature_requested",
              "signed",
              "submitted",
              "confirmed",
              "completed",
              "failed"
            ],
            "example": "created"
          },
          "status_reasons": {
            "description": "Reasons for the current status",
            "nullable": true,
            "example": [],
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/StatusReason"
            }
          },
          "created_at": {
            "type": "string",
            "description": "Step creation timestamp",
            "format": "date-time",
            "example": "2024-03-01T10:00:00.000Z"
          },
          "updated_at": {
            "type": "string",
            "description": "Step last update timestamp",
            "format": "date-time",
            "example": "2024-03-01T10:00:00.000Z"
          },
          "signature_requested_at": {
            "type": "string",
            "description": "Timestamp when a signature was requested for the step",
            "format": "date-time",
            "nullable": true,
            "example": null
          },
          "signed_at": {
            "type": "string",
            "description": "Timestamp when the step was cryptographically signed",
            "format": "date-time",
            "nullable": true,
            "example": null
          },
          "submitted_at": {
            "type": "string",
            "description": "Timestamp when step was submitted",
            "format": "date-time",
            "nullable": true,
            "example": null
          },
          "confirmed_at": {
            "type": "string",
            "description": "Timestamp when step was confirmed",
            "format": "date-time",
            "nullable": true,
            "example": null
          },
          "completed_at": {
            "type": "string",
            "description": "Timestamp when step completed",
            "format": "date-time",
            "nullable": true,
            "example": null
          },
          "failed_at": {
            "type": "string",
            "description": "Timestamp when step failed",
            "format": "date-time",
            "nullable": true,
            "example": null
          }
        },
        "required": [
          "id",
          "withdrawal_id",
          "step_sequence",
          "step_type",
          "estimated",
          "actual",
          "fees",
          "status",
          "created_at",
          "updated_at"
        ]
      },
      "WithdrawalStepActualFromLeg": {
        "type": "object",
        "properties": {
          "account_id": {
            "type": "string",
            "description": "Account ID.",
            "nullable": true
          },
          "amount": {
            "type": "string",
            "description": "Amount.",
            "nullable": true
          },
          "currency": {
            "type": "string",
            "description": "Currency code.",
            "nullable": true
          },
          "network": {
            "type": "string",
            "description": "Blockchain network.",
            "nullable": true
          }
        },
        "description": "Source side.",
        "required": [
          "account_id",
          "amount",
          "currency",
          "network"
        ]
      },
      "WithdrawalStepActualOverlay": {
        "type": "object",
        "properties": {
          "from": {
            "$ref": "#/components/schemas/WithdrawalStepActualFromLeg"
          },
          "to": {
            "$ref": "#/components/schemas/WithdrawalStepActualToLeg"
          }
        },
        "description": "Settled values once the step reaches a terminal state. All-null until then.",
        "required": [
          "from",
          "to"
        ]
      },
      "WithdrawalStepActualToLeg": {
        "type": "object",
        "properties": {
          "account_id": {
            "type": "string",
            "description": "Account ID.",
            "nullable": true
          },
          "amount": {
            "type": "string",
            "description": "Amount.",
            "nullable": true
          },
          "currency": {
            "type": "string",
            "description": "Currency code.",
            "nullable": true
          },
          "network": {
            "type": "string",
            "description": "Blockchain network.",
            "nullable": true
          }
        },
        "description": "Destination side.",
        "required": [
          "account_id",
          "amount",
          "currency",
          "network"
        ]
      },
      "WithdrawalStepEstimatedFromLeg": {
        "type": "object",
        "properties": {
          "account_id": {
            "type": "string",
            "description": "Account ID.",
            "nullable": true
          },
          "amount": {
            "type": "string",
            "description": "Amount.",
            "nullable": true
          },
          "currency": {
            "type": "string",
            "description": "Currency code.",
            "nullable": true
          },
          "network": {
            "type": "string",
            "description": "Blockchain network.",
            "nullable": true
          }
        },
        "description": "Source side.",
        "required": [
          "account_id",
          "amount",
          "currency",
          "network"
        ]
      },
      "WithdrawalStepEstimatedOverlay": {
        "type": "object",
        "properties": {
          "from": {
            "$ref": "#/components/schemas/WithdrawalStepEstimatedFromLeg"
          },
          "to": {
            "$ref": "#/components/schemas/WithdrawalStepEstimatedToLeg"
          }
        },
        "description": "Planned values for this step.",
        "required": [
          "from",
          "to"
        ]
      },
      "WithdrawalStepEstimatedToLeg": {
        "type": "object",
        "properties": {
          "account_id": {
            "type": "string",
            "description": "Account ID.",
            "nullable": true
          },
          "amount": {
            "type": "string",
            "description": "Amount.",
            "nullable": true
          },
          "currency": {
            "type": "string",
            "description": "Currency code.",
            "nullable": true
          },
          "network": {
            "type": "string",
            "description": "Blockchain network.",
            "nullable": true
          }
        },
        "description": "Destination side.",
        "required": [
          "account_id",
          "amount",
          "currency",
          "network"
        ]
      }
    }
  }
}
