openapi: 3.0.3 info: title: Ava Protocol AVS Auth Wallets API version: 1.0.0 description: 'Public REST API for the Ava Protocol AVS aggregator. Exposes workflow creation, execution monitoring, smart-wallet management, and related operations. Authentication is a single credential type — a JWT bearer token — obtained either via the wallet-signing flow (`POST /auth:exchange`) or out-of-band via the operator-run `create-api-key` CLI. Every request must include `Authorization: Bearer `. ' servers: - url: https://gateway.avaprotocol.org/api/v1 description: Production gateway - url: https://gateway-staging.avaprotocol.org/api/v1 description: Staging gateway - url: http://localhost:8080/api/v1 description: Local dev security: - bearerAuth: [] tags: - name: Wallets description: Smart-wallet derivation and operations paths: /wallets: get: tags: - Wallets summary: List the authenticated user's smart wallets operationId: listWallets responses: '200': description: All wallets for the authenticated user. content: application/json: schema: $ref: '#/components/schemas/WalletList' '401': $ref: '#/components/responses/Unauthorized' post: tags: - Wallets summary: Derive (and persist) a smart wallet address from (owner, salt, factory) description: 'Idempotent "ensure exists". Returns the deterministic CREATE2-derived address. POST (not GET) because it persists a wallet record server-side as a side effect of the derivation. ' operationId: createWallet requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CreateWalletRequest' responses: '200': description: Wallet derived (existing record returned if already present). content: application/json: schema: $ref: '#/components/schemas/Wallet' '201': description: Wallet derived (new record persisted). content: application/json: schema: $ref: '#/components/schemas/Wallet' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' /wallets/{address}: parameters: - name: address in: path required: true schema: $ref: '#/components/schemas/EthereumAddress' patch: tags: - Wallets summary: Update wallet properties description: Partial update; only fields present in the body are changed (e.g., `isHidden`). operationId: updateWallet requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/UpdateWalletRequest' responses: '200': description: Wallet updated. content: application/json: schema: $ref: '#/components/schemas/Wallet' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' /wallets/{address}:withdraw: parameters: - name: address in: path required: true schema: $ref: '#/components/schemas/EthereumAddress' post: tags: - Wallets summary: Withdraw funds from a smart wallet operationId: withdrawWallet requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/WithdrawRequest' responses: '200': description: Withdrawal submitted (UserOp may still be in flight). content: application/json: schema: $ref: '#/components/schemas/WithdrawResponse' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' '412': description: Insufficient balance or other on-chain precondition failure. content: application/problem+json: schema: $ref: '#/components/schemas/Problem' /wallets/{address}:getNonce: parameters: - name: address in: path required: true schema: $ref: '#/components/schemas/EthereumAddress' - $ref: '#/components/parameters/ChainIdQuery' get: tags: - Wallets summary: Get the smart wallet's current nonce operationId: getWalletNonce responses: '200': description: Wallet nonce. content: application/json: schema: $ref: '#/components/schemas/NonceResponse' '401': $ref: '#/components/responses/Unauthorized' '404': $ref: '#/components/responses/NotFound' components: schemas: Wallet: type: object required: - address - salt properties: address: $ref: '#/components/schemas/EthereumAddress' salt: type: string description: Salt used in CREATE2 derivation (decimal string). factoryAddress: $ref: '#/components/schemas/EthereumAddress' description: Factory contract used to derive this address. isHidden: type: boolean totalWorkflowCount: type: integer format: int64 enabledWorkflowCount: type: integer format: int64 completedWorkflowCount: type: integer format: int64 failedWorkflowCount: type: integer format: int64 disabledWorkflowCount: type: integer format: int64 WithdrawResponse: type: object required: - status properties: status: type: string enum: - pending - confirmed - failed message: type: string userOpHash: $ref: '#/components/schemas/Hex' transactionHash: $ref: '#/components/schemas/Hex' submittedAt: type: integer format: int64 smartWalletAddress: $ref: '#/components/schemas/EthereumAddress' recipientAddress: $ref: '#/components/schemas/EthereumAddress' amount: type: string token: type: string NonceResponse: type: object required: - nonce properties: nonce: type: string description: Smart wallet nonce as a decimal string. UpdateWalletRequest: type: object properties: isHidden: type: boolean Problem: type: object description: 'RFC 7807 problem+json. Returned as `application/problem+json` on any 4xx/5xx response. `type` and `title` describe the error class; `detail` is human-readable; `instance` is a per-request identifier suitable for log correlation. ' required: - type - title - status properties: type: type: string format: uri description: URI identifying the problem type. example: https://docs.avaprotocol.org/errors/workflow-not-found title: type: string description: Short, human-readable summary. example: Workflow not found status: type: integer format: int32 description: HTTP status code (echoed for clients that surface only the body). example: 404 detail: type: string description: Human-readable explanation specific to this occurrence. example: No workflow with id 01JG2FE5MDVKBPHEG0PEYSDKAC for owner 0xabc... instance: type: string description: URI / opaque ID identifying this specific occurrence (e.g., request id). example: req_01JG2FE5MFKTH0754RGF2DMVY7 code: type: string description: 'Machine-readable error code. Stable across releases; clients can switch on this for programmatic handling. Mirrors the gRPC-era ErrorCode enum vocabulary. ' example: WORKFLOW_NOT_FOUND ChainId: type: integer format: int64 description: 'Numeric chain ID (e.g. 11155111 for Sepolia, 8453 for Base). On chain-aware trigger/node configs this is required and must be a configured chain; on query/filter params it is optional. ' example: 11155111 EthereumAddress: type: string pattern: ^0x[a-fA-F0-9]{40}$ description: Lowercase or checksummed hex EOA / contract address. example: '0x82F2Dd9a552a69f2ceD7Ff2D05c43aB8430158FB' CreateWalletRequest: type: object required: - salt properties: salt: type: string description: Salt as a decimal string (big-int). Determines the derived address together with the factory. factoryAddress: $ref: '#/components/schemas/EthereumAddress' description: Optional factory override. Defaults to the aggregator's configured factory. chainId: $ref: '#/components/schemas/ChainId' description: 'Chain to derive the wallet on. Optional override — when omitted, the gateway defaults to the JWT `aud` chain (i.e. the chain the caller signed the auth message for). Set this when minting a wallet for a chain different from the one the JWT was issued against; the JWT proves EOA ownership, which is chain-independent. ' WithdrawRequest: type: object required: - recipientAddress - amount - token properties: recipientAddress: $ref: '#/components/schemas/EthereumAddress' amount: type: string description: Amount in wei (decimal string) or `max` for the full balance. token: type: string description: '`ETH` for native token, or an ERC-20 contract address.' chainId: $ref: '#/components/schemas/ChainId' description: Chain to execute the withdrawal on. 0 = aggregator default. WalletList: type: object required: - data properties: data: type: array items: $ref: '#/components/schemas/Wallet' Hex: type: string pattern: ^0x[a-fA-F0-9]*$ description: Arbitrary-length hex-encoded byte string. responses: Unauthorized: description: Missing or invalid bearer token. content: application/problem+json: schema: $ref: '#/components/schemas/Problem' NotFound: description: Resource not found. content: application/problem+json: schema: $ref: '#/components/schemas/Problem' BadRequest: description: Request validation failed. content: application/problem+json: schema: $ref: '#/components/schemas/Problem' parameters: ChainIdQuery: name: chainId in: query description: 'The chain to operate on (a single value). Omit to use the aggregator default (the request''s JWT `aud` chain, then the gateway default). ' schema: type: integer format: int64 securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT description: 'JWT bearer token. Obtained via `POST /auth:exchange` (wallet signature flow) or via the operator-run `create-api-key` CLI (long-lived, server-to-server). Send on every request as `Authorization: Bearer `. '