{
 "openapi": "3.0.3",
 "info": {
  "title": "Waltsoft EscrowPulse API",
  "version": "1.0.0",
  "description": "USDC escrow on Solana for AI agents. Generated Oct 15 2026 from the live API (LISTING-FIX-RUNBOOK step 4)."
 },
 "servers": [
  {
   "url": "https://escrowpulse.waltsoft.net/v1"
  }
 ],
 "security": [
  {
   "ApiKeyAuth": []
  }
 ],
 "paths": {
  "/escrow": {
   "post": {
    "operationId": "createEscrow",
    "summary": "Create an escrow; returns the deposit address and Solana Pay reference",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "$ref": "#/components/schemas/CreateEscrowRequest"
       },
       "example": {
        "amount_usd": 0.01,
        "worker_address": "DGKTTdYf5rVsSbLuAbGyqVCckLLkowtdqRhvqEZmmwFp",
        "principal_address": "DGKTTdYf5rVsSbLuAbGyqVCckLLkowtdqRhvqEZmmwFp",
        "condition": "Contract test escrow (never funded)",
        "expires_hours": 1
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK (billed)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/CreatedEscrow"
        }
       }
      }
     },
     "400": {
      "description": "Invalid input (not billed)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "Invalid or inactive API key, or X-Escrow-Signature does not verify",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "No API key sent: x402 challenge",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "Escrow not found",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "Rate limited",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "503": {
      "description": "Key check unavailable; retry",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/escrow/{escrow_id}": {
   "get": {
    "operationId": "getEscrow",
    "summary": "Escrow status, deposit and payout transactions",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "parameters": [
     {
      "name": "escrow_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "example": "esc_da4a0ea4a58443b8"
      },
      "example": "esc_da4a0ea4a58443b8"
     }
    ],
    "responses": {
     "200": {
      "description": "OK (billed)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Escrow"
        }
       }
      }
     },
     "400": {
      "description": "Invalid input (not billed)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "Invalid or inactive API key, or X-Escrow-Signature does not verify",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "No API key sent: x402 challenge",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "Escrow not found",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "Rate limited",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "503": {
      "description": "Key check unavailable; retry",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/escrow/{escrow_id}/release": {
   "post": {
    "operationId": "releaseEscrow",
    "summary": "Principal approves: the worker is paid. Signed with X-Escrow-Signature",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "parameters": [
     {
      "name": "escrow_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "example": "esc_da4a0ea4a58443b8"
      },
      "example": "esc_da4a0ea4a58443b8"
     },
     {
      "name": "X-Escrow-Signature",
      "in": "header",
      "required": false,
      "description": "Base58 ed25519 signature of \"EscrowPulse:<release|dispute>:<escrow_id>\" by the principal (release) or the principal/worker (dispute)",
      "schema": {
       "type": "string"
      }
     }
    ],
    "x-contract-expect": 403,
    "x-contract-e2e": "payments/escrowpulse/scripts/e2e-live.py marketplace",
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "proof_type": {
          "type": "string"
         },
         "proof_data": {
          "type": "string"
         }
        }
       },
       "example": {
        "proof_type": "signed_hash",
        "proof_data": "sha256:00"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK (billed)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Released"
        }
       }
      }
     },
     "400": {
      "description": "Invalid input (not billed)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "Invalid or inactive API key, or X-Escrow-Signature does not verify",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "No API key sent: x402 challenge",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "Escrow not found",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "Rate limited",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "503": {
      "description": "Key check unavailable; retry",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "Caller is not the principal or worker (no or wrong signature): not billed; the body carries message_to_sign",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "Escrow not funded, expired, or payout confirming",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    },
    "x-a2a-skip": "needs the X-Escrow-Signature header (a party's wallet signature), which an A2A message cannot carry"
   }
  },
  "/escrow/{escrow_id}/dispute": {
   "post": {
    "operationId": "disputeEscrow",
    "summary": "Principal or worker disputes a funded escrow (locks it). Signed with X-Escrow-Signature",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "parameters": [
     {
      "name": "escrow_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "example": "esc_da4a0ea4a58443b8"
      },
      "example": "esc_da4a0ea4a58443b8"
     },
     {
      "name": "X-Escrow-Signature",
      "in": "header",
      "required": false,
      "description": "Base58 ed25519 signature of \"EscrowPulse:<release|dispute>:<escrow_id>\" by the principal (release) or the principal/worker (dispute)",
      "schema": {
       "type": "string"
      }
     }
    ],
    "x-contract-expect": 403,
    "x-contract-e2e": "payments/escrowpulse/scripts/e2e-live.py approval",
    "requestBody": {
     "required": false,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "properties": {
         "reason": {
          "type": "string"
         }
        }
       },
       "example": {
        "reason": "work not delivered"
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "OK (billed)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Disputed"
        }
       }
      }
     },
     "400": {
      "description": "Invalid input (not billed)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "Invalid or inactive API key, or X-Escrow-Signature does not verify",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "No API key sent: x402 challenge",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "Escrow not found",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "Rate limited",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "503": {
      "description": "Key check unavailable; retry",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "403": {
      "description": "Caller is not the principal or worker (no or wrong signature): not billed; the body carries message_to_sign",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "409": {
      "description": "Escrow not funded, expired, or payout confirming",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    },
    "x-a2a-skip": "needs the X-Escrow-Signature header (a party's wallet signature), which an A2A message cannot carry"
   }
  },
  "/escrow/{escrow_id}/history": {
   "get": {
    "operationId": "getEscrowHistory",
    "summary": "Every event of an escrow, oldest first",
    "security": [
     {
      "ApiKeyAuth": []
     }
    ],
    "parameters": [
     {
      "name": "escrow_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "example": "esc_da4a0ea4a58443b8"
      },
      "example": "esc_da4a0ea4a58443b8"
     }
    ],
    "responses": {
     "200": {
      "description": "OK (billed)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/History"
        }
       }
      }
     },
     "400": {
      "description": "Invalid input (not billed)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "401": {
      "description": "Invalid or inactive API key, or X-Escrow-Signature does not verify",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "402": {
      "description": "No API key sent: x402 challenge",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "404": {
      "description": "Escrow not found",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "429": {
      "description": "Rate limited",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     },
     "503": {
      "description": "Key check unavailable; retry",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  }
 },
 "components": {
  "securitySchemes": {
   "ApiKeyAuth": {
    "type": "apiKey",
    "in": "header",
    "name": "X-API-Key"
   }
  },
  "schemas": {
   "CreateEscrowRequest": {
    "type": "object",
    "required": [
     "amount_usd",
     "worker_address",
     "principal_address",
     "condition",
     "expires_hours"
    ],
    "properties": {
     "amount_usd": {
      "type": "number",
      "minimum": 0.01,
      "maximum": 10000,
      "description": "Amount the worker receives, USD (USDC)"
     },
     "worker_address": {
      "type": "string",
      "description": "Worker's Solana address (base58); receives the payout"
     },
     "principal_address": {
      "type": "string",
      "description": "Principal's Solana address (base58); deposits and approves release"
     },
     "condition": {
      "type": "string",
      "maxLength": 500,
      "description": "What the worker must deliver"
     },
     "description": {
      "type": "string"
     },
     "expires_hours": {
      "type": "integer",
      "minimum": 1,
      "maximum": 720,
      "description": "Hours until an unreleased escrow refunds the principal"
     }
    }
   },
   "Escrow": {
    "type": "object",
    "required": [
     "escrow_id",
     "status",
     "amount_usd",
     "fee_usd",
     "total_to_deposit_usd",
     "deposit_address",
     "deposit_reference",
     "funded_at",
     "released_at",
     "expires_at",
     "worker_address",
     "principal_address",
     "condition",
     "tx_deposit",
     "proof_submitted_at",
     "proof_type",
     "proof_data",
     "proof",
     "tx_release",
     "tx_refund"
    ],
    "properties": {
     "escrow_id": {
      "type": "string"
     },
     "status": {
      "type": "string"
     },
     "amount_usd": {
      "type": "number"
     },
     "fee_usd": {
      "type": "number"
     },
     "total_to_deposit_usd": {
      "type": "number"
     },
     "deposit_address": {
      "type": "string"
     },
     "deposit_reference": {
      "type": "string"
     },
     "funded_at": {
      "type": "string",
      "nullable": true
     },
     "released_at": {
      "type": "string",
      "nullable": true
     },
     "expires_at": {
      "type": "string"
     },
     "worker_address": {
      "type": "string"
     },
     "principal_address": {
      "type": "string"
     },
     "condition": {
      "type": "string"
     },
     "tx_deposit": {
      "type": "string",
      "nullable": true
     },
     "proof_submitted_at": {
      "type": "string",
      "nullable": true
     },
     "proof_type": {
      "type": "string",
      "nullable": true
     },
     "proof_data": {
      "type": "string",
      "nullable": true
     },
     "proof": {
      "type": "object",
      "nullable": true
     },
     "tx_release": {
      "type": "string",
      "nullable": true
     },
     "tx_refund": {
      "type": "string",
      "nullable": true
     }
    },
    "description": "Every field is always present (null until it applies). While a release or refund transfer is confirming, the response also carries payout_in_flight: {kind, signature}."
   },
   "CreatedEscrow": {
    "type": "object",
    "required": [
     "escrow_id",
     "status",
     "deposit_address",
     "deposit_reference",
     "amount_usd",
     "fee_usd",
     "total_to_deposit_usd",
     "solana_pay_url",
     "deposit_instructions",
     "expires_at",
     "worker_address",
     "condition"
    ],
    "properties": {
     "escrow_id": {
      "type": "string"
     },
     "status": {
      "type": "string"
     },
     "deposit_address": {
      "type": "string"
     },
     "deposit_reference": {
      "type": "string"
     },
     "amount_usd": {
      "type": "number"
     },
     "fee_usd": {
      "type": "number"
     },
     "total_to_deposit_usd": {
      "type": "number"
     },
     "solana_pay_url": {
      "type": "string"
     },
     "deposit_instructions": {
      "type": "string"
     },
     "expires_at": {
      "type": "string"
     },
     "worker_address": {
      "type": "string"
     },
     "condition": {
      "type": "string"
     }
    }
   },
   "History": {
    "type": "object",
    "required": [
     "escrow_id",
     "events"
    ],
    "properties": {
     "escrow_id": {
      "type": "string"
     },
     "events": {
      "type": "array",
      "items": {
       "type": "object",
       "required": [
        "event_id",
        "event_type",
        "timestamp"
       ],
       "properties": {
        "event_id": {
         "type": "string"
        },
        "event_type": {
         "type": "string"
        },
        "timestamp": {
         "type": "string"
        },
        "data": {
         "type": "object"
        }
       }
      }
     }
    }
   },
   "Released": {
    "type": "object",
    "required": [
     "escrow_id",
     "status",
     "released_to",
     "tx_release",
     "amount_usd"
    ],
    "properties": {
     "escrow_id": {
      "type": "string"
     },
     "status": {
      "type": "string"
     },
     "released_to": {
      "type": "string"
     },
     "tx_release": {
      "type": "string"
     },
     "amount_usd": {
      "type": "number"
     },
     "message": {
      "type": "string"
     }
    }
   },
   "Disputed": {
    "type": "object",
    "required": [
     "escrow_id",
     "status"
    ],
    "properties": {
     "escrow_id": {
      "type": "string"
     },
     "status": {
      "type": "string"
     },
     "message": {
      "type": "string"
     }
    }
   },
   "Error": {
    "type": "object",
    "properties": {
     "error": {
      "oneOf": [
       {
        "type": "string"
       },
       {
        "type": "object",
        "properties": {
         "code": {
          "type": "integer"
         },
         "message": {
          "type": "string"
         }
        }
       }
      ]
     },
     "code": {
      "type": "string"
     },
     "message_to_sign": {
      "type": "string"
     }
    }
   }
  }
 }
}