{
  "x-generated-warning": "⚠️ This file is auto-generated. Do not edit manually",
  "openapi": "3.1.0",
  "info": {
    "title": "👤 Smart Wallets",
    "version": "1.0"
  },
  "servers": [
    {
      "url": "https://api.g.alchemy.com/signer/v1"
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "paths": {
    "/auth": {
      "post": {
        "summary": "Send Auth Email",
        "description": "Sends a user an email containing a magic link for authentication, allowing them to complete the login process and access their Smart Wallet through a secure, simple email verification method. Developers can customize the appearance and content of the authentication email through Alchemy dashboard to align with their application's branding and user experience requirements.\n",
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-readme": {
          "samples-languages": [
            "javascript",
            "curl",
            "python",
            "go"
          ]
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "description": "The email address of the user requesting access. This is where the authentication email, containing the magic link, will be sent.",
                    "type": "string"
                  },
                  "targetPublicKey": {
                    "type": "string",
                    "description": "Authentication of a client is done via an HPKE flow that allows the client and TEE to exchange an encrypted bundle without revealing it to a middleman (you, us, or Turnkey). The targetPublicKey is the public key that the client uses to decrypt the shared secret.\n\nSee more in the [Turnkey Docs](https://docs.turnkey.com/embedded-wallets/sub-organization-auth).\n"
                  },
                  "expirationSeconds": {
                    "type": "string",
                    "description": "Specifies the duration of the login session in seconds. After this period, the user has to re-login to refresh their session. The default value is 900 seconds (15 minutes).\n"
                  },
                  "redirectParams": {
                    "type": "string",
                    "description": "Redirect parameters appended to the magic link."
                  }
                },
                "required": [
                  "email",
                  "targetPublicKey"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Authentication email sent successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "orgId": {
                      "description": "The organization ID associated with the user and the application, facilitating the authentication process within the context of the user's application.",
                      "type": "string"
                    },
                    "otpId": {
                      "type": "string",
                      "description": "OTP request identifier"
                    }
                  },
                  "required": [
                    "orgId"
                  ]
                }
              }
            }
          }
        },
        "operationId": "sendEmailAuth"
      }
    },
    "/whoami": {
      "post": {
        "summary": "Authenticate User",
        "description": "Authenticates a user and returns their identity and wallet information, enabling the application to grant the user access to their Smart Wallet functionalities. This endpoint is used to confirm user authentication via email or passkey, thereby authorizing them to perform actions as the owner of a smart account or to conduct transactions as an EOA signer. It ensures that only authenticated users can access and manage their wallets.\n",
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-readme": {
          "samples-languages": [
            "javascript",
            "curl",
            "python",
            "go"
          ]
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "stampedRequest": {
                    "description": "A stamped [Turnkey Whoami Request](https://docs.turnkey.com/api#tag/Sessions/operation/GetWhoami).\n",
                    "type": "object",
                    "properties": {
                      "url": {
                        "type": "string",
                        "description": "Generated by the turnkey client, but will be ignored on our end."
                      },
                      "body": {
                        "type": "string",
                        "description": "JSON stringified request body."
                      },
                      "stamp": {
                        "type": "object",
                        "description": "A JSON-encoded object containing stamping information.\n",
                        "properties": {
                          "stampHeaderName": {
                            "type": "string",
                            "description": "For WebAuthN based stamps, this should be `X-Stamp-Webauthn`. For all other stamps, this should be `X-Stamp`.\n"
                          },
                          "stampHeaderValue": {
                            "type": "string",
                            "description": "The stamp over the request body. See the [Turnkey Stamps Documentation](https://docs.turnkey.com/api-design/stamps) for information on the format of this value.\n"
                          }
                        },
                        "required": [
                          "stampHeaderName",
                          "stampHeaderValue"
                        ]
                      }
                    },
                    "required": [
                      "body",
                      "stamp"
                    ]
                  }
                },
                "required": [
                  "stampedRequest"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "User authentication successful.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "email": {
                      "description": "The authenticated user's email address.",
                      "type": "string"
                    },
                    "userId": {
                      "type": "string",
                      "description": "A unique identifier for the authenticated user."
                    },
                    "orgId": {
                      "description": "The organization ID associated with the authenticated user's account.",
                      "type": "string"
                    },
                    "address": {
                      "type": "string",
                      "description": "The Ethereum address of the user's signer. Essential for executing transactions and managing the wallet."
                    },
                    "solanaAddress": {
                      "type": "string",
                      "description": "The Solana address of the user's signer. Required for Solana transactions and wallet management."
                    }
                  },
                  "required": [
                    "userId",
                    "orgId",
                    "address"
                  ]
                }
              }
            }
          }
        },
        "operationId": "authUser"
      }
    },
    "/lookup": {
      "post": {
        "summary": "Get User",
        "description": "Enables applications to query the existence of a user wallet based on an email address.\n",
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-readme": {
          "samples-languages": [
            "javascript",
            "curl",
            "python",
            "go"
          ]
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "description": "The email address of the user to look up. This is used to verify if an associated account exists within the system.",
                    "type": "string"
                  }
                },
                "required": [
                  "email"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Query successful. Returns organization ID if an account exists for the provided email address.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "orgId": {
                      "description": "The organization ID associated with the user. This ID is returned if an account exists for the given email address. If no account is found, this value will be null. The response is intentionally limited to this information to protect user privacy and security.\n",
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "operationId": "getUser"
      }
    },
    "/otp": {
      "post": {
        "summary": "Verify OTP Code",
        "description": "Verifies a one-time password (OTP) code sent to the user's email for authentication. This endpoint allows users to complete the authentication process by providing the OTP code they received, enabling secure access to their Smart Wallet functionalities.\n",
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-readme": {
          "samples-languages": [
            "javascript",
            "curl",
            "python",
            "go"
          ]
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "otpCode": {
                    "type": "string",
                    "description": "The one-time password code sent to the user's email or phone number. This code is typically 6-8 digits long and expires after a short period."
                  },
                  "otpId": {
                    "description": "The OTP request identifier returned from the initial authentication request. This links the verification attempt to the original OTP generation.",
                    "type": "string"
                  },
                  "orgId": {
                    "type": "string",
                    "description": "The organization ID associated with the user and application, enabling the management of Smart Wallets."
                  },
                  "targetPublicKey": {
                    "type": "string",
                    "description": "Authentication of a client is done via an HPKE flow that allows the client and TEE to exchange an encrypted bundle without revealing it to a middleman (you, us, or Turnkey). The targetPublicKey is the public key that the client uses to decrypt the shared secret.\n\nSee more in the [Turnkey Docs](https://docs.turnkey.com/embedded-wallets/sub-organization-auth).\n"
                  },
                  "expirationSeconds": {
                    "type": "string",
                    "description": "Specifies the duration of the login session in seconds. After this period, the user has to re-login to refresh their session. The default value is 900 seconds (15 minutes).\n"
                  }
                },
                "required": [
                  "orgId",
                  "otpCode",
                  "otpId",
                  "targetPublicKey"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OTP verification successful. User is now authenticated.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "credentialBundle": {
                      "type": "string",
                      "description": "An encrypted API key credential bundle that can be used for subsequent authenticated requests. This bundle contains the authentication credentials encrypted with the provided targetPublicKey and can be decrypted client-side for stamping requests."
                    }
                  },
                  "required": [
                    "credentialBundle"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid OTP code or expired OTP.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Error message describing why the OTP verification failed."
                    },
                    "code": {
                      "type": "string",
                      "description": "Error code for programmatic handling of the error."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many OTP verification attempts. Please wait before trying again.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Error message indicating rate limiting is in effect."
                    },
                    "retryAfter": {
                      "type": "integer",
                      "description": "Number of seconds to wait before making another verification attempt."
                    }
                  }
                }
              }
            }
          }
        },
        "operationId": "verifyOtp"
      }
    },
    "/auth-jwt": {
      "post": {
        "summary": "Authenticate with JWT",
        "description": "Authenticates an existing user using a JSON Web Token (JWT) for secure access to their Smart Wallet functionality. New user signup and wallet pregeneration are no longer supported as of June 16, 2026 because Alchemy Signer APIs are being sunset.\n",
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-readme": {
          "samples-languages": [
            "javascript",
            "curl",
            "python",
            "go"
          ]
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "jwt": {
                    "type": "string",
                    "description": "The JSON Web Token (JWT) used for authentication. The JWT must be a valid OIDC ID Token containing the required claims for user identification and authentication.\n**Required OIDC Claims:**\n- `iss` (Issuer): The identity of the OIDC provider. Should be the same as issuer URL specified in your /.well-known/openid-configuration, for example see the [Google OpenID configuration](https://accounts.google.com/.well-known/openid-configuration)\n- `sub` (Subject): A unique identifier that identifies the user with this auth provider.\n- `aud` (Audience): A unique identifier for the project that can be found on the [Alchemy Dashboard](https://dashboard.alchemy.com/apps/latest/services/smart-wallets).\n- `exp` (Expiration): Token expiration time as Unix timestamp\n- `iat` (Issued At): Token issuance time as Unix timestamp\n- `nonce` (Nonce): toHex(sha256(targetPublicKey)) without the leading 0x\n**Example JWT Payload:**\n```json\n{\n  \"iss\": \"https://accounts.google.com\",\n  \"sub\": \"1234567890abcdef\",\n  \"aud\": \"project_id\",\n  \"exp\": 1640995200,\n  \"iat\": 1640991600,\n  \"nonce\": \"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\n}\n```\n",
                    "example": "eyJhbGciOiJSUzI1NiIsImtpZCI6Im15LWtl..."
                  },
                  "targetPublicKey": {
                    "description": "Required for authentication. Optional for pregeneration.",
                    "type": "string"
                  },
                  "expirationSeconds": {
                    "type": "string",
                    "description": "Specifies the duration of the login session in seconds. After this period, the user has to re-login to refresh their session. The default value is 900 seconds (15 minutes).\n"
                  }
                },
                "required": [
                  "jwt"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JWT authentication successful. User is now authenticated or wallet has been pregenerated.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "isSignup": {
                      "type": "boolean",
                      "description": "Deprecated. New signups are no longer supported.",
                      "default": false
                    },
                    "orgId": {
                      "description": "The organization ID associated with the authenticated user and the application.",
                      "type": "string"
                    },
                    "credentialBundle": {
                      "type": "string",
                      "description": "An encrypted API key credential bundle that shall be used for subsequent authenticated requests. This bundle contains the authentication credentials encrypted with the provided targetPublicKey and can be decrypted client-side for stamping requests. A credential bundle will be returned when this endpoint is being used for authentication and would require a targetPublicKey in the request params"
                    },
                    "userId": {
                      "type": "string",
                      "description": "A unique identifier for the authenticated user."
                    },
                    "address": {
                      "type": "string",
                      "description": "The Ethereum address of the user's signer, available after successful authentication."
                    },
                    "solanaAddress": {
                      "type": "string",
                      "description": "The Solana address of the user's signer, available after successful authentication."
                    }
                  },
                  "required": [
                    "orgId",
                    "isSignUp"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Invalid JWT token or authentication failed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Error message describing why the JWT authentication failed."
                    },
                    "code": {
                      "type": "string",
                      "description": "Error code for programmatic handling of the error."
                    },
                    "details": {
                      "type": "object",
                      "description": "Additional details about the authentication failure, such as expired token, invalid signature, or missing claims.",
                      "additionalProperties": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized - JWT token is invalid, expired, or malformed.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Error message indicating the JWT token is not valid for authentication."
                    },
                    "tokenError": {
                      "type": "string",
                      "description": "Specific details about why the JWT token was rejected."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many authentication attempts. Please wait before trying again.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string",
                      "description": "Error message indicating rate limiting is in effect."
                    },
                    "retryAfter": {
                      "type": "integer",
                      "description": "Number of seconds to wait before making another authentication attempt."
                    }
                  }
                }
              }
            }
          }
        },
        "operationId": "authJwt"
      }
    },
    "/sign-payload": {
      "post": {
        "summary": "Sign Message",
        "description": "Allows for the signing of arbitrary payloads using the authenticated user's signer. The payload to be signed should be included within the body of a stamped request, ensuring the integrity and authenticity of the message to be signed. This operation is important for executing transactions and interactions on the blockchain that require verified signatures from the user's wallet.\n",
        "security": [
          {
            "apiKey": []
          }
        ],
        "x-readme": {
          "samples-languages": [
            "javascript",
            "curl",
            "python",
            "go"
          ]
        },
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "stampedRequest": {
                    "description": "A stamped request that includes the payload to be signed. The payload is part of the stamped request's body, which should conform to the structure outlined in the Turnkey API documentation for signing raw payloads.\n\nBecause users are given wallets for both Ethereum and Solana, it's possible to request signatures for both chains. The following is an example of the payload structure for signing bytes on Ethereum and Solana:\n\nSigning bytes for Ethereum:\n```\n{\n  organizationId: this.user.orgId,\n  type: \"ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2\",\n  timestampMs: Date.now().toString(),\n  parameters: {\n    encoding: \"PAYLOAD_ENCODING_HEXADECIMAL\",\n    hashFunction: \"HASH_FUNCTION_NO_OP\",\n    payload: msg,\n    signWith: this.user.address,\n  },\n}\n```\n\nSigning bytes for Solana:\n```\n{\n  organizationId: this.user.orgId,\n  type: \"ACTIVITY_TYPE_SIGN_RAW_PAYLOAD_V2\",\n  timestampMs: Date.now().toString(),\n  parameters: {\n    encoding: \"PAYLOAD_ENCODING_HEXADECIMAL\",\n    hashFunction: \"HASH_FUNCTION_NOT_APPLICABLE\",\n    payload: msg,\n    signWith: this.user.solanaAddress,\n  },\n}\n```\n\nFor more details on the parameters of the request body, see [Turnkey's API Reference](https://docs.turnkey.com/api#tag/Signing/operation/SignRawPayload).\n",
                    "type": "object",
                    "properties": {
                      "url": {
                        "type": "string",
                        "description": "Generated by the turnkey client, but will be ignored on our end."
                      },
                      "body": {
                        "type": "string",
                        "description": "JSON stringified request body."
                      },
                      "stamp": {
                        "type": "object",
                        "description": "A JSON-encoded object containing stamping information.\n",
                        "properties": {
                          "stampHeaderName": {
                            "type": "string",
                            "description": "For WebAuthN based stamps, this should be `X-Stamp-Webauthn`. For all other stamps, this should be `X-Stamp`.\n"
                          },
                          "stampHeaderValue": {
                            "type": "string",
                            "description": "The stamp over the request body. See the [Turnkey Stamps Documentation](https://docs.turnkey.com/api-design/stamps) for information on the format of this value.\n"
                          }
                        },
                        "required": [
                          "stampHeaderName",
                          "stampHeaderValue"
                        ]
                      }
                    },
                    "required": [
                      "body",
                      "stamp"
                    ]
                  }
                },
                "required": [
                  "stampedRequest"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Message signing successful.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "signature": {
                      "type": "string",
                      "description": "The signature generated for the specified payload."
                    }
                  },
                  "required": [
                    "signature"
                  ]
                }
              }
            }
          }
        },
        "operationId": "signMessage"
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "Bearer token authentication. Use 'Bearer <apiKey>' as the value.",
        "x-default": "Bearer API_KEY"
      }
    },
    "schemas": {
      "SignedTurnkeyRequest": {
        "type": "object",
        "description": "The signed request object containing session information. It is used to ensure the integrity and authenticity of requests to our API. For detailed steps on how to create a stamped request refer to the [Turnkey Stamps Documentation](https://docs.turnkey.com/api-design/stamps).\n",
        "properties": {
          "url": {
            "type": "string",
            "description": "Generated by the turnkey client, but will be ignored on our end."
          },
          "body": {
            "type": "string",
            "description": "JSON stringified request body."
          },
          "stamp": {
            "type": "object",
            "description": "A JSON-encoded object containing stamping information.\n",
            "properties": {
              "stampHeaderName": {
                "type": "string",
                "description": "For WebAuthN based stamps, this should be `X-Stamp-Webauthn`. For all other stamps, this should be `X-Stamp`.\n"
              },
              "stampHeaderValue": {
                "type": "string",
                "description": "The stamp over the request body. See the [Turnkey Stamps Documentation](https://docs.turnkey.com/api-design/stamps) for information on the format of this value.\n"
              }
            },
            "required": [
              "stampHeaderName",
              "stampHeaderValue"
            ]
          }
        },
        "required": [
          "body",
          "stamp"
        ]
      }
    }
  }
}
