{
  "openapi": "3.1.0",
  "info": {
    "title": "CapSign API",
    "version": "1.0.0",
    "description": "\n# Introduction\n\nThe CapSign API provides programmatic access to tokenized securities, digital equity management, and compliant investment workflows. Built on Base (Ethereum L2), CapSign enables you to:\n\n- **Manage Wallets** - Create and manage smart contract wallets with multi-signature support\n- **Issue Tokens** - Create equity, debt, and convertible securities tokens\n- **Run Offerings** - Launch compliant securities offerings with investor onboarding\n- **Handle Documents** - Manage and sign legal documents on-chain\n- **Track Compliance** - Verify investor qualifications and maintain compliance records\n\n## Authentication\n\nAll API requests require authentication using an API key. Include your API key in the `Authorization` header:\n\n```\nAuthorization: Bearer csk_live_your_api_key_here\n```\n\nOr use the `X-API-Key` header:\n\n```\nX-API-Key: csk_live_your_api_key_here\n```\n\n## Environments\n\nCapSign provides two environments:\n\n| Environment | API Key Prefix | Network |\n|-------------|----------------|---------|\n| Sandbox | `csk_test_` | Base Sepolia (testnet) |\n| Production | `csk_live_` | Base Mainnet |\n\n## Rate Limits\n\nAPI requests are rate-limited per API key. Rate limit headers are included in every response:\n\n- `X-RateLimit-Limit`: Maximum requests per minute\n- `X-RateLimit-Remaining`: Remaining requests in current window\n- `X-RateLimit-Reset`: Unix timestamp when the limit resets\n\n## Errors\n\nAll errors return a consistent JSON structure:\n\n```json\n{\n  \"error\": {\n    \"message\": \"Human-readable error message\",\n    \"code\": \"error_code\",\n    \"details\": {}\n  }\n}\n```\n\nCommon error codes:\n- `bad_request` (400) - Invalid request parameters\n- `unauthorized` (401) - Missing or invalid API key\n- `forbidden` (403) - Valid key but insufficient permissions\n- `not_found` (404) - Resource not found\n- `rate_limit_exceeded` (429) - Too many requests\n- `internal_error` (500) - Server error\n    ",
    "contact": {
      "name": "CapSign Support",
      "email": "api@capsign.com",
      "url": "https://capsign.com/support"
    },
    "license": {
      "name": "Business Source License 1.1",
      "url": "https://github.com/capsign/protocol/blob/main/LICENSE"
    }
  },
  "servers": [
    {
      "url": "https://capsign.com/api/v1",
      "description": "Production"
    },
    {
      "url": "https://testnet.capsign.com/api/v1",
      "description": "Sandbox (Testnet)"
    }
  ],
  "tags": [
    {
      "name": "Wallets",
      "description": "Smart contract wallet management"
    },
    {
      "name": "Tokens",
      "description": "Securities token operations"
    },
    {
      "name": "Offerings",
      "description": "Securities offerings and investments"
    },
    {
      "name": "Documents",
      "description": "Document management and signatures"
    },
    {
      "name": "Webhooks",
      "description": "Webhook configuration and events"
    },
    {
      "name": "API Keys",
      "description": "API key management"
    }
  ],
  "paths": {
    "/": {
      "get": {
        "summary": "API Status",
        "description": "Get API version and status information",
        "tags": [
          "General"
        ],
        "responses": {
          "200": {
            "description": "API status information",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "name": {
                      "type": "string",
                      "example": "CapSign API"
                    },
                    "version": {
                      "type": "string",
                      "example": "1.0.0"
                    },
                    "status": {
                      "type": "string",
                      "example": "operational"
                    },
                    "timestamp": {
                      "type": "string",
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/wallets": {
      "get": {
        "summary": "List Wallets",
        "description": "Retrieve a list of wallets accessible to your account",
        "tags": [
          "Wallets"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            },
            "description": "Page number for pagination"
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            },
            "description": "Number of results per page"
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "individual",
                "entity",
                "joint",
                "trust"
              ]
            },
            "description": "Filter by account type"
          }
        ],
        "responses": {
          "200": {
            "description": "List of wallets",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Wallet"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      },
      "post": {
        "summary": "Create Wallet",
        "description": "Create a new smart contract wallet. The wallet address is predicted using CREATE2 but must be deployed separately.",
        "tags": [
          "Wallets"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWalletRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Wallet created successfully",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Wallet"
                    },
                    "message": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          }
        }
      }
    },
    "/wallets/{address}": {
      "get": {
        "summary": "Get Wallet",
        "description": "Retrieve detailed information about a specific wallet",
        "tags": [
          "Wallets"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "address",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Wallet address (0x...)"
          }
        ],
        "responses": {
          "200": {
            "description": "Wallet details",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "$ref": "#/components/schemas/Wallet"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          }
        }
      }
    },
    "/tokens": {
      "get": {
        "summary": "List Tokens",
        "description": "Retrieve tokens from the blockchain. Queries the subgraph for indexed token data.",
        "tags": [
          "Tokens"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 20,
              "maximum": 100
            }
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "EquityToken",
                "Safe",
                "PromissoryNote"
              ]
            },
            "description": "Filter by token type"
          },
          {
            "name": "issuer",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by issuer address"
          }
        ],
        "responses": {
          "200": {
            "description": "List of tokens",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Token"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create Token",
        "description": "Create a new securities token configuration. Returns deployment data to execute on-chain.",
        "tags": [
          "Tokens"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateTokenRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Token configuration created"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        }
      }
    },
    "/offerings": {
      "get": {
        "summary": "List Offerings",
        "description": "Retrieve securities offerings from the blockchain",
        "tags": [
          "Offerings"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "ACTIVE",
                "COMPLETED",
                "CANCELLED"
              ]
            }
          },
          {
            "name": "issuer",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Filter by issuer address"
          }
        ],
        "responses": {
          "200": {
            "description": "List of offerings",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Offering"
                      }
                    },
                    "pagination": {
                      "$ref": "#/components/schemas/Pagination"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create Offering",
        "description": "Create a new securities offering configuration",
        "tags": [
          "Offerings"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateOfferingRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Offering configuration created"
          }
        }
      }
    },
    "/webhooks": {
      "get": {
        "summary": "List Webhooks",
        "description": "Retrieve configured webhook endpoints",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of webhooks",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "data": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Webhook"
                      }
                    },
                    "availableEvents": {
                      "type": "object"
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Create Webhook",
        "description": "Create a new webhook endpoint to receive event notifications",
        "tags": [
          "Webhooks"
        ],
        "security": [
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateWebhookRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook created"
          }
        }
      }
    },
    "/keys": {
      "get": {
        "summary": "List API Keys",
        "description": "List all API keys for your account. Requires session authentication.",
        "tags": [
          "API Keys"
        ],
        "responses": {
          "200": {
            "description": "List of API keys"
          }
        }
      },
      "post": {
        "summary": "Create API Key",
        "description": "Create a new API key. The full key is only shown once.",
        "tags": [
          "API Keys"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateApiKeyRequest"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "API key created"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key authentication. Use your API key as the bearer token."
      }
    },
    "schemas": {
      "Wallet": {
        "type": "object",
        "description": "Smart wallet with account ownership and optional settings",
        "properties": {
          "id": {
            "type": "string"
          },
          "address": {
            "type": "string",
            "description": "Ethereum address (0x...)"
          },
          "type": {
            "type": "string",
            "enum": [
              "SMART_CONTRACT",
              "EOA"
            ]
          },
          "custodyType": {
            "type": "string",
            "enum": [
              "SELF_CUSTODY",
              "REGULATED_CUSTODIAN"
            ]
          },
          "purpose": {
            "type": "string"
          },
          "isDeployed": {
            "type": "boolean"
          },
          "account": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "type": {
                "type": "string",
                "enum": [
                  "INDIVIDUAL",
                  "ENTITY",
                  "JOINT",
                  "TRUST"
                ]
              },
              "name": {
                "type": "string"
              },
              "status": {
                "type": "string"
              }
            }
          },
          "owners": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "EOA",
                    "Passkey",
                    "SmartWallet"
                  ]
                },
                "address": {
                  "type": "string"
                },
                "isPrimary": {
                  "type": "boolean"
                },
                "label": {
                  "type": "string"
                }
              }
            }
          },
          "settings": {
            "type": "object",
            "description": "Wallet-specific settings (included in detail responses)",
            "nullable": true,
            "properties": {
              "taxLotMethod": {
                "type": "string",
                "enum": [
                  "FIFO",
                  "LIFO",
                  "HIFO",
                  "SPECIFIC_LOT"
                ]
              },
              "hasMultiSig": {
                "type": "boolean"
              },
              "requiredSigners": {
                "type": "integer"
              },
              "hasTimelock": {
                "type": "boolean"
              },
              "timelockDuration": {
                "type": "integer",
                "description": "Duration in seconds"
              }
            }
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "updatedAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CreateWalletRequest": {
        "type": "object",
        "required": [
          "name",
          "ownerAddress"
        ],
        "properties": {
          "name": {
            "type": "string",
            "description": "Wallet name"
          },
          "accountType": {
            "type": "string",
            "enum": [
              "individual",
              "entity",
              "joint",
              "trust"
            ],
            "default": "entity"
          },
          "ownerAddress": {
            "type": "string",
            "description": "Owner wallet address"
          },
          "ownerType": {
            "type": "string",
            "enum": [
              "EOA",
              "SmartWallet"
            ],
            "default": "SmartWallet"
          },
          "signature": {
            "type": "string",
            "description": "Required for EOA owners"
          },
          "legalName": {
            "type": "string"
          },
          "displayName": {
            "type": "string"
          },
          "country": {
            "type": "string",
            "description": "ISO 3166-1 alpha-2 country code"
          },
          "state": {
            "type": "string"
          },
          "legalForm": {
            "type": "string"
          },
          "includeVehicleFacets": {
            "type": "boolean",
            "default": false
          }
        }
      },
      "Token": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "symbol": {
            "type": "string"
          },
          "decimals": {
            "type": "integer"
          },
          "totalSupply": {
            "type": "string"
          },
          "tokenType": {
            "type": "string",
            "enum": [
              "EquityToken",
              "Safe",
              "PromissoryNote"
            ]
          },
          "category": {
            "type": "string",
            "enum": [
              "EQUITY",
              "DEBT",
              "CONVERTIBLE",
              "DERIVATIVE"
            ]
          },
          "admin": {
            "type": "string"
          },
          "paused": {
            "type": "boolean"
          },
          "retired": {
            "type": "boolean"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CreateTokenRequest": {
        "type": "object",
        "required": [
          "name",
          "symbol",
          "issuerAddress"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "symbol": {
            "type": "string",
            "maxLength": 10
          },
          "tokenType": {
            "type": "string",
            "enum": [
              "EquityToken",
              "Safe",
              "PromissoryNote"
            ],
            "default": "EquityToken"
          },
          "issuerAddress": {
            "type": "string"
          },
          "maxSupply": {
            "type": "string",
            "default": "0",
            "description": "0 = unlimited"
          },
          "decimals": {
            "type": "integer",
            "default": 0,
            "description": "Number of decimal places (0 for equity/LP units, 6 for USDC-denominated instruments, 18 for ETH-denominated)"
          },
          "investorAddress": {
            "type": "string",
            "description": "Bilateral SAFE only - investor wallet address"
          },
          "investmentAmount": {
            "type": "string",
            "description": "Bilateral SAFE only - investment amount in payment token smallest unit"
          },
          "paymentToken": {
            "type": "string",
            "description": "Bilateral SAFE only - payment token address (e.g. USDC)"
          },
          "valuationCap": {
            "type": "string",
            "description": "Bilateral SAFE only - valuation cap in payment token smallest unit (0 = uncapped)"
          },
          "discountBasisPoints": {
            "type": "integer",
            "description": "Bilateral SAFE only - discount rate in basis points (e.g. 2000 = 20%)"
          },
          "hasMFN": {
            "type": "boolean",
            "description": "Bilateral SAFE only - most favored nation clause"
          },
          "hasProRata": {
            "type": "boolean",
            "description": "Bilateral SAFE only - pro-rata participation rights"
          },
          "principalAmount": {
            "type": "string",
            "description": "PromissoryNote only"
          },
          "interestRate": {
            "type": "integer",
            "description": "PromissoryNote only, basis points"
          },
          "maturityDate": {
            "type": "string",
            "format": "date-time",
            "description": "PromissoryNote only"
          },
          "complianceModules": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "Offering": {
        "type": "object",
        "properties": {
          "address": {
            "type": "string"
          },
          "issuer": {
            "type": "string"
          },
          "token": {
            "type": "object",
            "properties": {
              "address": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "symbol": {
                "type": "string"
              }
            }
          },
          "pricePerToken": {
            "type": "string"
          },
          "minInvestment": {
            "type": "string"
          },
          "maxAmount": {
            "type": "string"
          },
          "deadline": {
            "type": "string",
            "format": "date-time"
          },
          "totalInvested": {
            "type": "string"
          },
          "investorCount": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "DRAFT",
              "ACTIVE",
              "COMPLETED",
              "CANCELLED"
            ]
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CreateOfferingRequest": {
        "type": "object",
        "required": [
          "name",
          "tokenAddress",
          "issuerAddress",
          "pricePerToken",
          "maxAmount"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "tokenAddress": {
            "type": "string"
          },
          "issuerAddress": {
            "type": "string"
          },
          "paymentToken": {
            "type": "string"
          },
          "pricePerToken": {
            "type": "string"
          },
          "minInvestment": {
            "type": "string"
          },
          "maxAmount": {
            "type": "string"
          },
          "deadline": {
            "type": "string",
            "format": "date-time"
          },
          "generalSolicitation": {
            "type": "boolean",
            "default": false
          },
          "complianceModules": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "Webhook": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "environment": {
            "type": "string",
            "enum": [
              "SANDBOX",
              "PRODUCTION"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "ACTIVE",
              "PAUSED",
              "DISABLED"
            ]
          },
          "failureCount": {
            "type": "integer"
          },
          "lastSuccessAt": {
            "type": "string",
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          }
        }
      },
      "CreateWebhookRequest": {
        "type": "object",
        "required": [
          "url"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "HTTPS endpoint URL"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "default": [
              "*"
            ]
          },
          "environment": {
            "type": "string",
            "enum": [
              "SANDBOX",
              "PRODUCTION"
            ]
          }
        }
      },
      "CreateApiKeyRequest": {
        "type": "object",
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 3
          },
          "environment": {
            "type": "string",
            "enum": [
              "SANDBOX",
              "PRODUCTION"
            ],
            "default": "SANDBOX"
          },
          "permissions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "expiresIn": {
            "type": "integer",
            "description": "Days until expiration"
          },
          "rateLimit": {
            "type": "integer",
            "default": 1000
          }
        }
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer"
          },
          "limit": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "totalPages": {
            "type": "integer"
          },
          "hasMore": {
            "type": "boolean"
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "message": {
                "type": "string"
              },
              "code": {
                "type": "string"
              },
              "details": {
                "type": "object"
              }
            }
          }
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Authentication required or invalid API key",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "BadRequest": {
        "description": "Invalid request parameters",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "NotFound": {
        "description": "Resource not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "Conflict": {
        "description": "Resource already exists",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "Rate limit exceeded",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "integer"
            },
            "description": "Seconds until retry is allowed"
          }
        },
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    }
  }
}