From 3048ff06497bc9784ac8deb522b74969b32530f3 Mon Sep 17 00:00:00 2001 From: Dhruv Pareek Date: Wed, 8 Apr 2026 16:20:21 -0700 Subject: [PATCH] Add embedded wallets auth endpoints --- .stainless/stainless.yml | 26 + mintlify/openapi.yaml | 655 ++++++++++++++++++ openapi.yaml | 655 ++++++++++++++++++ .../EmbeddedWalletAuthCallbackRequest.yaml | 25 + .../EmbeddedWalletAuthInitRequest.yaml | 33 + .../EmbeddedWalletAuthMethod.yaml | 36 + ...EmbeddedWalletAuthMethodCreateRequest.yaml | 28 + .../EmbeddedWalletAuthMethodType.yaml | 14 + ...EmbeddedWalletAuthMethodUpdateRequest.yaml | 19 + .../EmbeddedWalletAuthOperationResponse.yaml | 49 ++ .../EmbeddedWalletAuthOtpInitRequest.yaml | 16 + .../EmbeddedWalletAuthOtpVerifyRequest.yaml | 18 + openapi/openapi.yaml | 16 + .../embedded_wallets_auth_callback.yaml | 49 ++ .../embedded_wallets_auth_init.yaml | 58 ++ .../embedded_wallets_auth_methods.yaml | 59 ++ ...d_wallets_auth_methods_{authMethodId}.yaml | 134 ++++ .../embedded_wallets_auth_otp_init.yaml | 56 ++ .../embedded_wallets_auth_otp_verify.yaml | 49 ++ 19 files changed, 1995 insertions(+) create mode 100644 openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthCallbackRequest.yaml create mode 100644 openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthInitRequest.yaml create mode 100644 openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthMethod.yaml create mode 100644 openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthMethodCreateRequest.yaml create mode 100644 openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthMethodType.yaml create mode 100644 openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthMethodUpdateRequest.yaml create mode 100644 openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthOperationResponse.yaml create mode 100644 openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthOtpInitRequest.yaml create mode 100644 openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthOtpVerifyRequest.yaml create mode 100644 openapi/paths/embedded-wallets/embedded_wallets_auth_callback.yaml create mode 100644 openapi/paths/embedded-wallets/embedded_wallets_auth_init.yaml create mode 100644 openapi/paths/embedded-wallets/embedded_wallets_auth_methods.yaml create mode 100644 openapi/paths/embedded-wallets/embedded_wallets_auth_methods_{authMethodId}.yaml create mode 100644 openapi/paths/embedded-wallets/embedded_wallets_auth_otp_init.yaml create mode 100644 openapi/paths/embedded-wallets/embedded_wallets_auth_otp_verify.yaml diff --git a/.stainless/stainless.yml b/.stainless/stainless.yml index a883c23b..8d638164 100644 --- a/.stainless/stainless.yml +++ b/.stainless/stainless.yml @@ -186,6 +186,32 @@ resources: vnd_account_info: "#/components/schemas/VndAccountInfo" # base_external_account_info: "#/components/schemas/BaseExternalAccountInfo" + embedded_wallets: + subresources: + auth: + models: + embedded_wallet_auth_init_request: "#/components/schemas/EmbeddedWalletAuthInitRequest" + embedded_wallet_auth_otp_init_request: "#/components/schemas/EmbeddedWalletAuthOtpInitRequest" + embedded_wallet_auth_otp_verify_request: "#/components/schemas/EmbeddedWalletAuthOtpVerifyRequest" + embedded_wallet_auth_callback_request: "#/components/schemas/EmbeddedWalletAuthCallbackRequest" + embedded_wallet_auth_operation_response: "#/components/schemas/EmbeddedWalletAuthOperationResponse" + methods: + init: post /embedded-wallets/auth/init + init_otp: post /embedded-wallets/auth/otp/init + verify_otp: post /embedded-wallets/auth/otp/verify + callback: post /embedded-wallets/auth/callback + auth_methods: + models: + embedded_wallet_auth_method_type: "#/components/schemas/EmbeddedWalletAuthMethodType" + embedded_wallet_auth_method: "#/components/schemas/EmbeddedWalletAuthMethod" + embedded_wallet_auth_method_create_request: "#/components/schemas/EmbeddedWalletAuthMethodCreateRequest" + embedded_wallet_auth_method_update_request: "#/components/schemas/EmbeddedWalletAuthMethodUpdateRequest" + embedded_wallet_auth_operation_response: "#/components/schemas/EmbeddedWalletAuthOperationResponse" + methods: + create: post /embedded-wallets/auth/methods + update: patch /embedded-wallets/auth/methods/{authMethodId} + delete: delete /embedded-wallets/auth/methods/{authMethodId} + transfer_in: models: transaction: "#/components/schemas/TransactionOneOf" diff --git a/mintlify/openapi.yaml b/mintlify/openapi.yaml index df604042..8f3fb3f5 100644 --- a/mintlify/openapi.yaml +++ b/mintlify/openapi.yaml @@ -26,6 +26,8 @@ tags: description: Endpoints for uploading and managing verification documents for customers and beneficial owners. Supports KYC and KYB document requirements. - name: Internal Accounts description: Internal account management endpoints for creating and managing internal accounts + - name: Embedded Wallets + description: Endpoints for initializing embedded wallet authentication flows and managing embedded wallet authentication methods. - name: External Accounts description: External account management endpoints for creating and managing external bank accounts - name: Same-Currency Transfers @@ -1187,6 +1189,413 @@ paths: application/json: schema: $ref: '#/components/schemas/Error500' + /embedded-wallets/auth/init: + post: + summary: Initialize embedded wallet authentication + description: | + Initialize an embedded wallet authentication flow for an existing internal + account. + + This endpoint is intended for the first-time setup flow. It may create the + underlying Turnkey sub-organization when one does not already exist, link it + to the provided internal account, and return the next step required to + complete the requested authentication method. + operationId: initEmbeddedWalletAuth + tags: + - Embedded Wallets + security: + - BasicAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthInitRequest' + responses: + '200': + description: Embedded wallet authentication flow initialized successfully + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthOperationResponse' + '400': + description: Bad request - Invalid embedded wallet auth initialization parameters + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + '404': + description: Internal account not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + '409': + description: Conflict - Embedded wallet auth flow is already in progress + content: + application/json: + schema: + $ref: '#/components/schemas/Error409' + '500': + description: Internal service error + content: + application/json: + schema: + $ref: '#/components/schemas/Error500' + /embedded-wallets/auth/otp/init: + post: + summary: Initialize an embedded wallet OTP challenge + description: | + Request a one-time password (OTP) challenge for a pending embedded wallet + action. + + This endpoint is used when the next step of the embedded wallet flow + requires OTP verification for authentication or action approval. + operationId: initEmbeddedWalletAuthOtp + tags: + - Embedded Wallets + security: + - BasicAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthOtpInitRequest' + responses: + '200': + description: OTP challenge initialized successfully + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthOperationResponse' + '400': + description: Bad request - Invalid OTP initialization parameters + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + '404': + description: Pending embedded wallet action not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + '409': + description: Conflict - OTP challenge is already active or cannot be created + content: + application/json: + schema: + $ref: '#/components/schemas/Error409' + '500': + description: Internal service error + content: + application/json: + schema: + $ref: '#/components/schemas/Error500' + /embedded-wallets/auth/otp/verify: + post: + summary: Verify an embedded wallet OTP challenge + description: | + Verify a previously issued embedded wallet OTP challenge and execute the + pending action associated with that challenge. + + This endpoint does not require partner API credentials. Instead, the OTP + code is supplied in the request body as part of the challenge verification. + operationId: verifyEmbeddedWalletAuthOtp + tags: + - Embedded Wallets + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthOtpVerifyRequest' + responses: + '200': + description: OTP challenge verified successfully + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthOperationResponse' + '400': + description: Bad request - Invalid or expired OTP code + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '404': + description: OTP challenge or pending embedded wallet action not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + '409': + description: Conflict - OTP challenge has already been used or cannot be completed + content: + application/json: + schema: + $ref: '#/components/schemas/Error409' + '500': + description: Internal service error + content: + application/json: + schema: + $ref: '#/components/schemas/Error500' + /embedded-wallets/auth/methods: + post: + summary: Create an embedded wallet auth method + description: | + Create a new authentication method for the embedded wallet associated with + the supplied Turnkey stamp. + + The request may create a passkey-based method immediately or return a + follow-up step for OTP or OAuth-based authentication methods. + operationId: createEmbeddedWalletAuthMethod + tags: + - Embedded Wallets + security: [] + parameters: + - name: X-Turnkey-Stamp + in: header + description: | + Turnkey stamp authorizing the request. The stamp may represent either a session stamp or a direct stamp. + required: true + schema: + type: string + example: stamp:session:eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9 + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthMethodCreateRequest' + responses: + '201': + description: Embedded wallet auth method created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthOperationResponse' + '400': + description: Bad request - Invalid auth method creation parameters + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '401': + description: Unauthorized - Turnkey stamp is invalid or expired + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + '409': + description: Conflict - Embedded wallet auth method already exists or cannot be created + content: + application/json: + schema: + $ref: '#/components/schemas/Error409' + '500': + description: Internal service error + content: + application/json: + schema: + $ref: '#/components/schemas/Error500' + /embedded-wallets/auth/methods/{authMethodId}: + patch: + summary: Update an embedded wallet auth method + description: | + Update the email address or phone number associated with an embedded wallet + auth method. + + The auth method to update is identified by `authMethodId`, while the + request is authorized with a Turnkey stamp. + operationId: updateEmbeddedWalletAuthMethod + tags: + - Embedded Wallets + security: [] + parameters: + - name: authMethodId + in: path + description: Unique identifier of the embedded wallet auth method to update + required: true + schema: + type: string + example: EmbeddedWalletAuthMethod:019542f5-b3e7-1d02-0000-000000000001 + - name: X-Turnkey-Stamp + in: header + description: | + Turnkey stamp authorizing the request. The stamp may represent either a session stamp or a direct stamp. + required: true + schema: + type: string + example: stamp:direct:eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9 + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthMethodUpdateRequest' + responses: + '200': + description: Embedded wallet auth method updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthOperationResponse' + '400': + description: Bad request - Invalid auth method update parameters + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '401': + description: Unauthorized - Turnkey stamp is invalid or expired + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + '404': + description: Embedded wallet auth method not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + '409': + description: Conflict - Embedded wallet auth method cannot be updated in its current state + content: + application/json: + schema: + $ref: '#/components/schemas/Error409' + '500': + description: Internal service error + content: + application/json: + schema: + $ref: '#/components/schemas/Error500' + delete: + summary: Delete an embedded wallet auth method + description: | + Delete an embedded wallet auth method. + + The request will be rejected when the specified auth method is the last + remaining authentication method for the embedded wallet. + operationId: deleteEmbeddedWalletAuthMethod + tags: + - Embedded Wallets + security: [] + parameters: + - name: authMethodId + in: path + description: Unique identifier of the embedded wallet auth method to delete + required: true + schema: + type: string + example: EmbeddedWalletAuthMethod:019542f5-b3e7-1d02-0000-000000000001 + - name: X-Turnkey-Stamp + in: header + description: | + Turnkey stamp authorizing the request. The stamp may represent either a session stamp or a direct stamp. + required: true + schema: + type: string + example: stamp:session:eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9 + responses: + '204': + description: Embedded wallet auth method deleted successfully + '400': + description: Bad request - Invalid auth method deletion parameters + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '401': + description: Unauthorized - Turnkey stamp is invalid or expired + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + '404': + description: Embedded wallet auth method not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + '409': + description: Conflict - Embedded wallet auth method is the last remaining method or cannot be deleted + content: + application/json: + schema: + $ref: '#/components/schemas/Error409' + '500': + description: Internal service error + content: + application/json: + schema: + $ref: '#/components/schemas/Error500' + /embedded-wallets/auth/callback: + post: + summary: Handle an embedded wallet OAuth callback + description: | + Complete an embedded wallet OAuth-based authentication flow after the user + has granted consent with the upstream OAuth provider. + + This endpoint does not require partner API credentials. The OAuth + authorization code is supplied in the request body. + operationId: callbackEmbeddedWalletAuth + tags: + - Embedded Wallets + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthCallbackRequest' + responses: + '200': + description: Embedded wallet OAuth callback handled successfully + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthOperationResponse' + '400': + description: Bad request - Invalid OAuth callback parameters + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '404': + description: OAuth flow or pending embedded wallet action not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + '409': + description: Conflict - OAuth callback has already been consumed or cannot be completed + content: + application/json: + schema: + $ref: '#/components/schemas/Error409' + '500': + description: Internal service error + content: + application/json: + schema: + $ref: '#/components/schemas/Error500' /beneficial-owners: post: summary: Create a beneficial owner @@ -9823,6 +10232,252 @@ components: example: ext_acc_123456 accountInfo: $ref: '#/components/schemas/ExternalAccountInfoOneOf' + EmbeddedWalletAuthMethodType: + type: string + description: | + Type of authentication method associated with an embedded wallet. + + | Value | Description | + |-------|-------------| + | PASSKEY | WebAuthn passkey-based authentication | + | OTP | One-time password delivered to an email address or phone number | + | OAUTH | Third-party OAuth-based authentication | + enum: + - PASSKEY + - OTP + - OAUTH + example: OTP + EmbeddedWalletAuthInitRequest: + type: object + required: + - internalAccountId + - authMethodType + properties: + internalAccountId: + type: string + description: Existing internal account to link to the embedded wallet + example: InternalAccount:019542f5-b3e7-1d02-0000-000000000001 + authMethodType: + $ref: '#/components/schemas/EmbeddedWalletAuthMethodType' + email: + type: string + format: email + description: Email address to use when initializing an email-based OTP or OAuth flow + example: alice@example.com + phoneNumber: + type: string + description: Phone number to use when initializing an SMS-based OTP flow + example: '+14155550123' + oauthProvider: + type: string + description: OAuth provider to use when `authMethodType` is `OAUTH` + example: GOOGLE + redirectUri: + type: string + format: uri + description: Redirect URI to receive the OAuth callback, when applicable + example: https://partner.example.com/embedded-wallet/callback + clientReferenceId: + type: string + description: Partner-defined reference to correlate the request with the partner application state + example: ew_init_123456 + EmbeddedWalletAuthMethod: + type: object + required: + - id + - methodType + - createdAt + - updatedAt + properties: + id: + type: string + description: Unique identifier of the embedded wallet auth method + example: EmbeddedWalletAuthMethod:019542f5-b3e7-1d02-0000-000000000001 + methodType: + $ref: '#/components/schemas/EmbeddedWalletAuthMethodType' + label: + type: string + description: Human-readable label or masked identifier for the auth method + example: al***@example.com + oauthProvider: + type: string + description: OAuth provider associated with the auth method, when applicable + example: GOOGLE + verifiedAt: + type: string + format: date-time + description: Timestamp when the auth method was verified and became active + example: '2026-04-08T15:32:28Z' + createdAt: + type: string + format: date-time + description: Creation timestamp + example: '2026-04-08T15:30:01Z' + updatedAt: + type: string + format: date-time + description: Last update timestamp + example: '2026-04-08T15:32:28Z' + EmbeddedWalletAuthOperationResponse: + type: object + required: + - status + - nextStep + properties: + embeddedWalletId: + type: string + description: Unique identifier of the embedded wallet associated with the operation + example: EmbeddedWallet:019542f5-b3e7-1d02-0000-000000000001 + authSessionId: + type: string + description: Unique identifier of the embedded wallet auth session, when applicable + example: EmbeddedWalletAuthSession:019542f5-b3e7-1d02-0000-000000000002 + pendingActionId: + type: string + description: Unique identifier of the pending embedded wallet action + example: EmbeddedWalletPendingAction:019542f5-b3e7-1d02-0000-000000000003 + otpChallengeId: + type: string + description: Unique identifier of the OTP challenge, when an OTP step is active + example: EmbeddedWalletOtpChallenge:019542f5-b3e7-1d02-0000-000000000004 + turnkeySubOrgId: + type: string + description: Turnkey sub-organization identifier associated with the embedded wallet + example: suborg_01JABCDEF23456789GHIJKL + status: + type: string + description: Current status of the embedded wallet auth-related operation + example: PENDING + nextStep: + type: string + description: Next action the integrator or end user must complete + example: COMPLETE_OTP_VERIFICATION + maskedDestination: + type: string + description: Masked email address or phone number used for OTP delivery + example: al***@example.com + oauthConsentUrl: + type: string + format: uri + description: OAuth consent URL the integrator should redirect the end user to, when applicable + example: https://accounts.google.com/o/oauth2/v2/auth?client_id=example-client-id + expiresAt: + type: string + format: date-time + description: Expiration timestamp for the current step of the auth flow + example: '2026-04-08T15:40:00Z' + authMethod: + $ref: '#/components/schemas/EmbeddedWalletAuthMethod' + EmbeddedWalletAuthOtpInitRequest: + type: object + required: + - pendingActionId + properties: + pendingActionId: + type: string + description: Pending embedded wallet action that requires OTP verification + example: EmbeddedWalletPendingAction:019542f5-b3e7-1d02-0000-000000000003 + deliveryMethod: + type: string + description: Preferred OTP delivery method for the challenge + example: EMAIL + resend: + type: boolean + description: Whether the request should invalidate the current OTP and send a new one + default: false + EmbeddedWalletAuthOtpVerifyRequest: + type: object + required: + - pendingActionId + - otpChallengeId + - otpCode + properties: + pendingActionId: + type: string + description: Pending embedded wallet action that is being authorized with the OTP + example: EmbeddedWalletPendingAction:019542f5-b3e7-1d02-0000-000000000003 + otpChallengeId: + type: string + description: OTP challenge issued for the pending action + example: EmbeddedWalletOtpChallenge:019542f5-b3e7-1d02-0000-000000000004 + otpCode: + type: string + description: One-time password submitted by the end user + example: '123456' + EmbeddedWalletAuthMethodCreateRequest: + type: object + required: + - methodType + properties: + methodType: + $ref: '#/components/schemas/EmbeddedWalletAuthMethodType' + email: + type: string + format: email + description: Email address to associate with the auth method, when applicable + example: alice@example.com + phoneNumber: + type: string + description: Phone number to associate with the auth method, when applicable + example: '+14155550123' + oauthProvider: + type: string + description: OAuth provider to use when `methodType` is `OAUTH` + example: GOOGLE + redirectUri: + type: string + format: uri + description: Redirect URI for OAuth-based auth method creation, when applicable + example: https://partner.example.com/embedded-wallet/callback + authenticatorName: + type: string + description: Friendly name for a passkey authenticator, when applicable + example: Alice MacBook Pro + EmbeddedWalletAuthMethodUpdateRequest: + type: object + description: | + Fields to update for an embedded wallet auth method. Provide only the fields relevant to the auth method being updated. + minProperties: 1 + properties: + email: + type: string + format: email + description: New email address for the embedded wallet auth method + example: alice.updated@example.com + phoneNumber: + type: string + description: New phone number for the embedded wallet auth method + example: '+14155550124' + label: + type: string + description: Updated user-facing label for the auth method + example: Primary recovery email + EmbeddedWalletAuthCallbackRequest: + type: object + required: + - authorizationCode + properties: + authorizationCode: + type: string + description: OAuth authorization code received after the user grants consent + example: 4/0AQSTgQF4-example-authorization-code + state: + type: string + description: Opaque OAuth state value used to correlate the callback to the original flow + example: oauth_state_123456 + redirectUri: + type: string + format: uri + description: Redirect URI used during the OAuth authorization request + example: https://partner.example.com/embedded-wallet/callback + pendingActionId: + type: string + description: Pending embedded wallet action associated with the OAuth callback + example: EmbeddedWalletPendingAction:019542f5-b3e7-1d02-0000-000000000003 + oauthProvider: + type: string + description: OAuth provider that issued the authorization code + example: GOOGLE BeneficialOwnerCreateRequest: type: object required: diff --git a/openapi.yaml b/openapi.yaml index df604042..8f3fb3f5 100644 --- a/openapi.yaml +++ b/openapi.yaml @@ -26,6 +26,8 @@ tags: description: Endpoints for uploading and managing verification documents for customers and beneficial owners. Supports KYC and KYB document requirements. - name: Internal Accounts description: Internal account management endpoints for creating and managing internal accounts + - name: Embedded Wallets + description: Endpoints for initializing embedded wallet authentication flows and managing embedded wallet authentication methods. - name: External Accounts description: External account management endpoints for creating and managing external bank accounts - name: Same-Currency Transfers @@ -1187,6 +1189,413 @@ paths: application/json: schema: $ref: '#/components/schemas/Error500' + /embedded-wallets/auth/init: + post: + summary: Initialize embedded wallet authentication + description: | + Initialize an embedded wallet authentication flow for an existing internal + account. + + This endpoint is intended for the first-time setup flow. It may create the + underlying Turnkey sub-organization when one does not already exist, link it + to the provided internal account, and return the next step required to + complete the requested authentication method. + operationId: initEmbeddedWalletAuth + tags: + - Embedded Wallets + security: + - BasicAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthInitRequest' + responses: + '200': + description: Embedded wallet authentication flow initialized successfully + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthOperationResponse' + '400': + description: Bad request - Invalid embedded wallet auth initialization parameters + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + '404': + description: Internal account not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + '409': + description: Conflict - Embedded wallet auth flow is already in progress + content: + application/json: + schema: + $ref: '#/components/schemas/Error409' + '500': + description: Internal service error + content: + application/json: + schema: + $ref: '#/components/schemas/Error500' + /embedded-wallets/auth/otp/init: + post: + summary: Initialize an embedded wallet OTP challenge + description: | + Request a one-time password (OTP) challenge for a pending embedded wallet + action. + + This endpoint is used when the next step of the embedded wallet flow + requires OTP verification for authentication or action approval. + operationId: initEmbeddedWalletAuthOtp + tags: + - Embedded Wallets + security: + - BasicAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthOtpInitRequest' + responses: + '200': + description: OTP challenge initialized successfully + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthOperationResponse' + '400': + description: Bad request - Invalid OTP initialization parameters + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + '404': + description: Pending embedded wallet action not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + '409': + description: Conflict - OTP challenge is already active or cannot be created + content: + application/json: + schema: + $ref: '#/components/schemas/Error409' + '500': + description: Internal service error + content: + application/json: + schema: + $ref: '#/components/schemas/Error500' + /embedded-wallets/auth/otp/verify: + post: + summary: Verify an embedded wallet OTP challenge + description: | + Verify a previously issued embedded wallet OTP challenge and execute the + pending action associated with that challenge. + + This endpoint does not require partner API credentials. Instead, the OTP + code is supplied in the request body as part of the challenge verification. + operationId: verifyEmbeddedWalletAuthOtp + tags: + - Embedded Wallets + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthOtpVerifyRequest' + responses: + '200': + description: OTP challenge verified successfully + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthOperationResponse' + '400': + description: Bad request - Invalid or expired OTP code + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '404': + description: OTP challenge or pending embedded wallet action not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + '409': + description: Conflict - OTP challenge has already been used or cannot be completed + content: + application/json: + schema: + $ref: '#/components/schemas/Error409' + '500': + description: Internal service error + content: + application/json: + schema: + $ref: '#/components/schemas/Error500' + /embedded-wallets/auth/methods: + post: + summary: Create an embedded wallet auth method + description: | + Create a new authentication method for the embedded wallet associated with + the supplied Turnkey stamp. + + The request may create a passkey-based method immediately or return a + follow-up step for OTP or OAuth-based authentication methods. + operationId: createEmbeddedWalletAuthMethod + tags: + - Embedded Wallets + security: [] + parameters: + - name: X-Turnkey-Stamp + in: header + description: | + Turnkey stamp authorizing the request. The stamp may represent either a session stamp or a direct stamp. + required: true + schema: + type: string + example: stamp:session:eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9 + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthMethodCreateRequest' + responses: + '201': + description: Embedded wallet auth method created successfully + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthOperationResponse' + '400': + description: Bad request - Invalid auth method creation parameters + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '401': + description: Unauthorized - Turnkey stamp is invalid or expired + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + '409': + description: Conflict - Embedded wallet auth method already exists or cannot be created + content: + application/json: + schema: + $ref: '#/components/schemas/Error409' + '500': + description: Internal service error + content: + application/json: + schema: + $ref: '#/components/schemas/Error500' + /embedded-wallets/auth/methods/{authMethodId}: + patch: + summary: Update an embedded wallet auth method + description: | + Update the email address or phone number associated with an embedded wallet + auth method. + + The auth method to update is identified by `authMethodId`, while the + request is authorized with a Turnkey stamp. + operationId: updateEmbeddedWalletAuthMethod + tags: + - Embedded Wallets + security: [] + parameters: + - name: authMethodId + in: path + description: Unique identifier of the embedded wallet auth method to update + required: true + schema: + type: string + example: EmbeddedWalletAuthMethod:019542f5-b3e7-1d02-0000-000000000001 + - name: X-Turnkey-Stamp + in: header + description: | + Turnkey stamp authorizing the request. The stamp may represent either a session stamp or a direct stamp. + required: true + schema: + type: string + example: stamp:direct:eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9 + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthMethodUpdateRequest' + responses: + '200': + description: Embedded wallet auth method updated successfully + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthOperationResponse' + '400': + description: Bad request - Invalid auth method update parameters + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '401': + description: Unauthorized - Turnkey stamp is invalid or expired + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + '404': + description: Embedded wallet auth method not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + '409': + description: Conflict - Embedded wallet auth method cannot be updated in its current state + content: + application/json: + schema: + $ref: '#/components/schemas/Error409' + '500': + description: Internal service error + content: + application/json: + schema: + $ref: '#/components/schemas/Error500' + delete: + summary: Delete an embedded wallet auth method + description: | + Delete an embedded wallet auth method. + + The request will be rejected when the specified auth method is the last + remaining authentication method for the embedded wallet. + operationId: deleteEmbeddedWalletAuthMethod + tags: + - Embedded Wallets + security: [] + parameters: + - name: authMethodId + in: path + description: Unique identifier of the embedded wallet auth method to delete + required: true + schema: + type: string + example: EmbeddedWalletAuthMethod:019542f5-b3e7-1d02-0000-000000000001 + - name: X-Turnkey-Stamp + in: header + description: | + Turnkey stamp authorizing the request. The stamp may represent either a session stamp or a direct stamp. + required: true + schema: + type: string + example: stamp:session:eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9 + responses: + '204': + description: Embedded wallet auth method deleted successfully + '400': + description: Bad request - Invalid auth method deletion parameters + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '401': + description: Unauthorized - Turnkey stamp is invalid or expired + content: + application/json: + schema: + $ref: '#/components/schemas/Error401' + '404': + description: Embedded wallet auth method not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + '409': + description: Conflict - Embedded wallet auth method is the last remaining method or cannot be deleted + content: + application/json: + schema: + $ref: '#/components/schemas/Error409' + '500': + description: Internal service error + content: + application/json: + schema: + $ref: '#/components/schemas/Error500' + /embedded-wallets/auth/callback: + post: + summary: Handle an embedded wallet OAuth callback + description: | + Complete an embedded wallet OAuth-based authentication flow after the user + has granted consent with the upstream OAuth provider. + + This endpoint does not require partner API credentials. The OAuth + authorization code is supplied in the request body. + operationId: callbackEmbeddedWalletAuth + tags: + - Embedded Wallets + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthCallbackRequest' + responses: + '200': + description: Embedded wallet OAuth callback handled successfully + content: + application/json: + schema: + $ref: '#/components/schemas/EmbeddedWalletAuthOperationResponse' + '400': + description: Bad request - Invalid OAuth callback parameters + content: + application/json: + schema: + $ref: '#/components/schemas/Error400' + '404': + description: OAuth flow or pending embedded wallet action not found + content: + application/json: + schema: + $ref: '#/components/schemas/Error404' + '409': + description: Conflict - OAuth callback has already been consumed or cannot be completed + content: + application/json: + schema: + $ref: '#/components/schemas/Error409' + '500': + description: Internal service error + content: + application/json: + schema: + $ref: '#/components/schemas/Error500' /beneficial-owners: post: summary: Create a beneficial owner @@ -9823,6 +10232,252 @@ components: example: ext_acc_123456 accountInfo: $ref: '#/components/schemas/ExternalAccountInfoOneOf' + EmbeddedWalletAuthMethodType: + type: string + description: | + Type of authentication method associated with an embedded wallet. + + | Value | Description | + |-------|-------------| + | PASSKEY | WebAuthn passkey-based authentication | + | OTP | One-time password delivered to an email address or phone number | + | OAUTH | Third-party OAuth-based authentication | + enum: + - PASSKEY + - OTP + - OAUTH + example: OTP + EmbeddedWalletAuthInitRequest: + type: object + required: + - internalAccountId + - authMethodType + properties: + internalAccountId: + type: string + description: Existing internal account to link to the embedded wallet + example: InternalAccount:019542f5-b3e7-1d02-0000-000000000001 + authMethodType: + $ref: '#/components/schemas/EmbeddedWalletAuthMethodType' + email: + type: string + format: email + description: Email address to use when initializing an email-based OTP or OAuth flow + example: alice@example.com + phoneNumber: + type: string + description: Phone number to use when initializing an SMS-based OTP flow + example: '+14155550123' + oauthProvider: + type: string + description: OAuth provider to use when `authMethodType` is `OAUTH` + example: GOOGLE + redirectUri: + type: string + format: uri + description: Redirect URI to receive the OAuth callback, when applicable + example: https://partner.example.com/embedded-wallet/callback + clientReferenceId: + type: string + description: Partner-defined reference to correlate the request with the partner application state + example: ew_init_123456 + EmbeddedWalletAuthMethod: + type: object + required: + - id + - methodType + - createdAt + - updatedAt + properties: + id: + type: string + description: Unique identifier of the embedded wallet auth method + example: EmbeddedWalletAuthMethod:019542f5-b3e7-1d02-0000-000000000001 + methodType: + $ref: '#/components/schemas/EmbeddedWalletAuthMethodType' + label: + type: string + description: Human-readable label or masked identifier for the auth method + example: al***@example.com + oauthProvider: + type: string + description: OAuth provider associated with the auth method, when applicable + example: GOOGLE + verifiedAt: + type: string + format: date-time + description: Timestamp when the auth method was verified and became active + example: '2026-04-08T15:32:28Z' + createdAt: + type: string + format: date-time + description: Creation timestamp + example: '2026-04-08T15:30:01Z' + updatedAt: + type: string + format: date-time + description: Last update timestamp + example: '2026-04-08T15:32:28Z' + EmbeddedWalletAuthOperationResponse: + type: object + required: + - status + - nextStep + properties: + embeddedWalletId: + type: string + description: Unique identifier of the embedded wallet associated with the operation + example: EmbeddedWallet:019542f5-b3e7-1d02-0000-000000000001 + authSessionId: + type: string + description: Unique identifier of the embedded wallet auth session, when applicable + example: EmbeddedWalletAuthSession:019542f5-b3e7-1d02-0000-000000000002 + pendingActionId: + type: string + description: Unique identifier of the pending embedded wallet action + example: EmbeddedWalletPendingAction:019542f5-b3e7-1d02-0000-000000000003 + otpChallengeId: + type: string + description: Unique identifier of the OTP challenge, when an OTP step is active + example: EmbeddedWalletOtpChallenge:019542f5-b3e7-1d02-0000-000000000004 + turnkeySubOrgId: + type: string + description: Turnkey sub-organization identifier associated with the embedded wallet + example: suborg_01JABCDEF23456789GHIJKL + status: + type: string + description: Current status of the embedded wallet auth-related operation + example: PENDING + nextStep: + type: string + description: Next action the integrator or end user must complete + example: COMPLETE_OTP_VERIFICATION + maskedDestination: + type: string + description: Masked email address or phone number used for OTP delivery + example: al***@example.com + oauthConsentUrl: + type: string + format: uri + description: OAuth consent URL the integrator should redirect the end user to, when applicable + example: https://accounts.google.com/o/oauth2/v2/auth?client_id=example-client-id + expiresAt: + type: string + format: date-time + description: Expiration timestamp for the current step of the auth flow + example: '2026-04-08T15:40:00Z' + authMethod: + $ref: '#/components/schemas/EmbeddedWalletAuthMethod' + EmbeddedWalletAuthOtpInitRequest: + type: object + required: + - pendingActionId + properties: + pendingActionId: + type: string + description: Pending embedded wallet action that requires OTP verification + example: EmbeddedWalletPendingAction:019542f5-b3e7-1d02-0000-000000000003 + deliveryMethod: + type: string + description: Preferred OTP delivery method for the challenge + example: EMAIL + resend: + type: boolean + description: Whether the request should invalidate the current OTP and send a new one + default: false + EmbeddedWalletAuthOtpVerifyRequest: + type: object + required: + - pendingActionId + - otpChallengeId + - otpCode + properties: + pendingActionId: + type: string + description: Pending embedded wallet action that is being authorized with the OTP + example: EmbeddedWalletPendingAction:019542f5-b3e7-1d02-0000-000000000003 + otpChallengeId: + type: string + description: OTP challenge issued for the pending action + example: EmbeddedWalletOtpChallenge:019542f5-b3e7-1d02-0000-000000000004 + otpCode: + type: string + description: One-time password submitted by the end user + example: '123456' + EmbeddedWalletAuthMethodCreateRequest: + type: object + required: + - methodType + properties: + methodType: + $ref: '#/components/schemas/EmbeddedWalletAuthMethodType' + email: + type: string + format: email + description: Email address to associate with the auth method, when applicable + example: alice@example.com + phoneNumber: + type: string + description: Phone number to associate with the auth method, when applicable + example: '+14155550123' + oauthProvider: + type: string + description: OAuth provider to use when `methodType` is `OAUTH` + example: GOOGLE + redirectUri: + type: string + format: uri + description: Redirect URI for OAuth-based auth method creation, when applicable + example: https://partner.example.com/embedded-wallet/callback + authenticatorName: + type: string + description: Friendly name for a passkey authenticator, when applicable + example: Alice MacBook Pro + EmbeddedWalletAuthMethodUpdateRequest: + type: object + description: | + Fields to update for an embedded wallet auth method. Provide only the fields relevant to the auth method being updated. + minProperties: 1 + properties: + email: + type: string + format: email + description: New email address for the embedded wallet auth method + example: alice.updated@example.com + phoneNumber: + type: string + description: New phone number for the embedded wallet auth method + example: '+14155550124' + label: + type: string + description: Updated user-facing label for the auth method + example: Primary recovery email + EmbeddedWalletAuthCallbackRequest: + type: object + required: + - authorizationCode + properties: + authorizationCode: + type: string + description: OAuth authorization code received after the user grants consent + example: 4/0AQSTgQF4-example-authorization-code + state: + type: string + description: Opaque OAuth state value used to correlate the callback to the original flow + example: oauth_state_123456 + redirectUri: + type: string + format: uri + description: Redirect URI used during the OAuth authorization request + example: https://partner.example.com/embedded-wallet/callback + pendingActionId: + type: string + description: Pending embedded wallet action associated with the OAuth callback + example: EmbeddedWalletPendingAction:019542f5-b3e7-1d02-0000-000000000003 + oauthProvider: + type: string + description: OAuth provider that issued the authorization code + example: GOOGLE BeneficialOwnerCreateRequest: type: object required: diff --git a/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthCallbackRequest.yaml b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthCallbackRequest.yaml new file mode 100644 index 00000000..a1811bbb --- /dev/null +++ b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthCallbackRequest.yaml @@ -0,0 +1,25 @@ +type: object +required: + - authorizationCode +properties: + authorizationCode: + type: string + description: OAuth authorization code received after the user grants consent + example: 4/0AQSTgQF4-example-authorization-code + state: + type: string + description: Opaque OAuth state value used to correlate the callback to the original flow + example: oauth_state_123456 + redirectUri: + type: string + format: uri + description: Redirect URI used during the OAuth authorization request + example: https://partner.example.com/embedded-wallet/callback + pendingActionId: + type: string + description: Pending embedded wallet action associated with the OAuth callback + example: EmbeddedWalletPendingAction:019542f5-b3e7-1d02-0000-000000000003 + oauthProvider: + type: string + description: OAuth provider that issued the authorization code + example: GOOGLE diff --git a/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthInitRequest.yaml b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthInitRequest.yaml new file mode 100644 index 00000000..c498df49 --- /dev/null +++ b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthInitRequest.yaml @@ -0,0 +1,33 @@ +type: object +required: + - internalAccountId + - authMethodType +properties: + internalAccountId: + type: string + description: Existing internal account to link to the embedded wallet + example: InternalAccount:019542f5-b3e7-1d02-0000-000000000001 + authMethodType: + $ref: ./EmbeddedWalletAuthMethodType.yaml + email: + type: string + format: email + description: Email address to use when initializing an email-based OTP or OAuth flow + example: alice@example.com + phoneNumber: + type: string + description: Phone number to use when initializing an SMS-based OTP flow + example: '+14155550123' + oauthProvider: + type: string + description: OAuth provider to use when `authMethodType` is `OAUTH` + example: GOOGLE + redirectUri: + type: string + format: uri + description: Redirect URI to receive the OAuth callback, when applicable + example: https://partner.example.com/embedded-wallet/callback + clientReferenceId: + type: string + description: Partner-defined reference to correlate the request with the partner application state + example: ew_init_123456 diff --git a/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthMethod.yaml b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthMethod.yaml new file mode 100644 index 00000000..29191e30 --- /dev/null +++ b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthMethod.yaml @@ -0,0 +1,36 @@ +type: object +required: + - id + - methodType + - createdAt + - updatedAt +properties: + id: + type: string + description: Unique identifier of the embedded wallet auth method + example: EmbeddedWalletAuthMethod:019542f5-b3e7-1d02-0000-000000000001 + methodType: + $ref: ./EmbeddedWalletAuthMethodType.yaml + label: + type: string + description: Human-readable label or masked identifier for the auth method + example: al***@example.com + oauthProvider: + type: string + description: OAuth provider associated with the auth method, when applicable + example: GOOGLE + verifiedAt: + type: string + format: date-time + description: Timestamp when the auth method was verified and became active + example: '2026-04-08T15:32:28Z' + createdAt: + type: string + format: date-time + description: Creation timestamp + example: '2026-04-08T15:30:01Z' + updatedAt: + type: string + format: date-time + description: Last update timestamp + example: '2026-04-08T15:32:28Z' diff --git a/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthMethodCreateRequest.yaml b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthMethodCreateRequest.yaml new file mode 100644 index 00000000..708324da --- /dev/null +++ b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthMethodCreateRequest.yaml @@ -0,0 +1,28 @@ +type: object +required: + - methodType +properties: + methodType: + $ref: ./EmbeddedWalletAuthMethodType.yaml + email: + type: string + format: email + description: Email address to associate with the auth method, when applicable + example: alice@example.com + phoneNumber: + type: string + description: Phone number to associate with the auth method, when applicable + example: '+14155550123' + oauthProvider: + type: string + description: OAuth provider to use when `methodType` is `OAUTH` + example: GOOGLE + redirectUri: + type: string + format: uri + description: Redirect URI for OAuth-based auth method creation, when applicable + example: https://partner.example.com/embedded-wallet/callback + authenticatorName: + type: string + description: Friendly name for a passkey authenticator, when applicable + example: Alice MacBook Pro diff --git a/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthMethodType.yaml b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthMethodType.yaml new file mode 100644 index 00000000..a492c87f --- /dev/null +++ b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthMethodType.yaml @@ -0,0 +1,14 @@ +type: string +description: | + Type of authentication method associated with an embedded wallet. + + | Value | Description | + |-------|-------------| + | PASSKEY | WebAuthn passkey-based authentication | + | OTP | One-time password delivered to an email address or phone number | + | OAUTH | Third-party OAuth-based authentication | +enum: + - PASSKEY + - OTP + - OAUTH +example: OTP diff --git a/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthMethodUpdateRequest.yaml b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthMethodUpdateRequest.yaml new file mode 100644 index 00000000..e224f319 --- /dev/null +++ b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthMethodUpdateRequest.yaml @@ -0,0 +1,19 @@ +type: object +description: > + Fields to update for an embedded wallet auth method. Provide only the fields + relevant to the auth method being updated. +minProperties: 1 +properties: + email: + type: string + format: email + description: New email address for the embedded wallet auth method + example: alice.updated@example.com + phoneNumber: + type: string + description: New phone number for the embedded wallet auth method + example: '+14155550124' + label: + type: string + description: Updated user-facing label for the auth method + example: Primary recovery email diff --git a/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthOperationResponse.yaml b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthOperationResponse.yaml new file mode 100644 index 00000000..440b9916 --- /dev/null +++ b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthOperationResponse.yaml @@ -0,0 +1,49 @@ +type: object +required: + - status + - nextStep +properties: + embeddedWalletId: + type: string + description: Unique identifier of the embedded wallet associated with the operation + example: EmbeddedWallet:019542f5-b3e7-1d02-0000-000000000001 + authSessionId: + type: string + description: Unique identifier of the embedded wallet auth session, when applicable + example: EmbeddedWalletAuthSession:019542f5-b3e7-1d02-0000-000000000002 + pendingActionId: + type: string + description: Unique identifier of the pending embedded wallet action + example: EmbeddedWalletPendingAction:019542f5-b3e7-1d02-0000-000000000003 + otpChallengeId: + type: string + description: Unique identifier of the OTP challenge, when an OTP step is active + example: EmbeddedWalletOtpChallenge:019542f5-b3e7-1d02-0000-000000000004 + turnkeySubOrgId: + type: string + description: Turnkey sub-organization identifier associated with the embedded wallet + example: suborg_01JABCDEF23456789GHIJKL + status: + type: string + description: Current status of the embedded wallet auth-related operation + example: PENDING + nextStep: + type: string + description: Next action the integrator or end user must complete + example: COMPLETE_OTP_VERIFICATION + maskedDestination: + type: string + description: Masked email address or phone number used for OTP delivery + example: al***@example.com + oauthConsentUrl: + type: string + format: uri + description: OAuth consent URL the integrator should redirect the end user to, when applicable + example: https://accounts.google.com/o/oauth2/v2/auth?client_id=example-client-id + expiresAt: + type: string + format: date-time + description: Expiration timestamp for the current step of the auth flow + example: '2026-04-08T15:40:00Z' + authMethod: + $ref: ./EmbeddedWalletAuthMethod.yaml diff --git a/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthOtpInitRequest.yaml b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthOtpInitRequest.yaml new file mode 100644 index 00000000..e817a0a2 --- /dev/null +++ b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthOtpInitRequest.yaml @@ -0,0 +1,16 @@ +type: object +required: + - pendingActionId +properties: + pendingActionId: + type: string + description: Pending embedded wallet action that requires OTP verification + example: EmbeddedWalletPendingAction:019542f5-b3e7-1d02-0000-000000000003 + deliveryMethod: + type: string + description: Preferred OTP delivery method for the challenge + example: EMAIL + resend: + type: boolean + description: Whether the request should invalidate the current OTP and send a new one + default: false diff --git a/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthOtpVerifyRequest.yaml b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthOtpVerifyRequest.yaml new file mode 100644 index 00000000..fcb84bfc --- /dev/null +++ b/openapi/components/schemas/embedded_wallets/EmbeddedWalletAuthOtpVerifyRequest.yaml @@ -0,0 +1,18 @@ +type: object +required: + - pendingActionId + - otpChallengeId + - otpCode +properties: + pendingActionId: + type: string + description: Pending embedded wallet action that is being authorized with the OTP + example: EmbeddedWalletPendingAction:019542f5-b3e7-1d02-0000-000000000003 + otpChallengeId: + type: string + description: OTP challenge issued for the pending action + example: EmbeddedWalletOtpChallenge:019542f5-b3e7-1d02-0000-000000000004 + otpCode: + type: string + description: One-time password submitted by the end user + example: '123456' diff --git a/openapi/openapi.yaml b/openapi/openapi.yaml index 113747c9..c8369dfb 100644 --- a/openapi/openapi.yaml +++ b/openapi/openapi.yaml @@ -28,6 +28,10 @@ tags: and beneficial owners. Supports KYC and KYB document requirements. - name: Internal Accounts description: Internal account management endpoints for creating and managing internal accounts + - name: Embedded Wallets + description: >- + Endpoints for initializing embedded wallet authentication flows and + managing embedded wallet authentication methods. - name: External Accounts description: External account management endpoints for creating and managing external bank accounts - name: Same-Currency Transfers @@ -105,6 +109,18 @@ paths: $ref: paths/customers/customers_external_accounts.yaml /platform/external-accounts: $ref: paths/platform/platform_external_accounts.yaml + /embedded-wallets/auth/init: + $ref: paths/embedded-wallets/embedded_wallets_auth_init.yaml + /embedded-wallets/auth/otp/init: + $ref: paths/embedded-wallets/embedded_wallets_auth_otp_init.yaml + /embedded-wallets/auth/otp/verify: + $ref: paths/embedded-wallets/embedded_wallets_auth_otp_verify.yaml + /embedded-wallets/auth/methods: + $ref: paths/embedded-wallets/embedded_wallets_auth_methods.yaml + /embedded-wallets/auth/methods/{authMethodId}: + $ref: paths/embedded-wallets/embedded_wallets_auth_methods_{authMethodId}.yaml + /embedded-wallets/auth/callback: + $ref: paths/embedded-wallets/embedded_wallets_auth_callback.yaml /beneficial-owners: $ref: paths/beneficial-owners/beneficial_owners.yaml /beneficial-owners/{beneficialOwnerId}: diff --git a/openapi/paths/embedded-wallets/embedded_wallets_auth_callback.yaml b/openapi/paths/embedded-wallets/embedded_wallets_auth_callback.yaml new file mode 100644 index 00000000..c64d524f --- /dev/null +++ b/openapi/paths/embedded-wallets/embedded_wallets_auth_callback.yaml @@ -0,0 +1,49 @@ +post: + summary: Handle an embedded wallet OAuth callback + description: | + Complete an embedded wallet OAuth-based authentication flow after the user + has granted consent with the upstream OAuth provider. + + This endpoint does not require partner API credentials. The OAuth + authorization code is supplied in the request body. + operationId: callbackEmbeddedWalletAuth + tags: + - Embedded Wallets + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: ../../components/schemas/embedded_wallets/EmbeddedWalletAuthCallbackRequest.yaml + responses: + '200': + description: Embedded wallet OAuth callback handled successfully + content: + application/json: + schema: + $ref: ../../components/schemas/embedded_wallets/EmbeddedWalletAuthOperationResponse.yaml + '400': + description: Bad request - Invalid OAuth callback parameters + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error400.yaml + '404': + description: OAuth flow or pending embedded wallet action not found + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error404.yaml + '409': + description: Conflict - OAuth callback has already been consumed or cannot be completed + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error409.yaml + '500': + description: Internal service error + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error500.yaml diff --git a/openapi/paths/embedded-wallets/embedded_wallets_auth_init.yaml b/openapi/paths/embedded-wallets/embedded_wallets_auth_init.yaml new file mode 100644 index 00000000..afca1091 --- /dev/null +++ b/openapi/paths/embedded-wallets/embedded_wallets_auth_init.yaml @@ -0,0 +1,58 @@ +post: + summary: Initialize embedded wallet authentication + description: | + Initialize an embedded wallet authentication flow for an existing internal + account. + + This endpoint is intended for the first-time setup flow. It may create the + underlying Turnkey sub-organization when one does not already exist, link it + to the provided internal account, and return the next step required to + complete the requested authentication method. + operationId: initEmbeddedWalletAuth + tags: + - Embedded Wallets + security: + - BasicAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: ../../components/schemas/embedded_wallets/EmbeddedWalletAuthInitRequest.yaml + responses: + '200': + description: Embedded wallet authentication flow initialized successfully + content: + application/json: + schema: + $ref: ../../components/schemas/embedded_wallets/EmbeddedWalletAuthOperationResponse.yaml + '400': + description: Bad request - Invalid embedded wallet auth initialization parameters + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error400.yaml + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error401.yaml + '404': + description: Internal account not found + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error404.yaml + '409': + description: Conflict - Embedded wallet auth flow is already in progress + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error409.yaml + '500': + description: Internal service error + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error500.yaml diff --git a/openapi/paths/embedded-wallets/embedded_wallets_auth_methods.yaml b/openapi/paths/embedded-wallets/embedded_wallets_auth_methods.yaml new file mode 100644 index 00000000..07b8db03 --- /dev/null +++ b/openapi/paths/embedded-wallets/embedded_wallets_auth_methods.yaml @@ -0,0 +1,59 @@ +post: + summary: Create an embedded wallet auth method + description: | + Create a new authentication method for the embedded wallet associated with + the supplied Turnkey stamp. + + The request may create a passkey-based method immediately or return a + follow-up step for OTP or OAuth-based authentication methods. + operationId: createEmbeddedWalletAuthMethod + tags: + - Embedded Wallets + security: [] + parameters: + - name: X-Turnkey-Stamp + in: header + description: > + Turnkey stamp authorizing the request. The stamp may represent either a + session stamp or a direct stamp. + required: true + schema: + type: string + example: stamp:session:eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9 + requestBody: + required: true + content: + application/json: + schema: + $ref: ../../components/schemas/embedded_wallets/EmbeddedWalletAuthMethodCreateRequest.yaml + responses: + '201': + description: Embedded wallet auth method created successfully + content: + application/json: + schema: + $ref: ../../components/schemas/embedded_wallets/EmbeddedWalletAuthOperationResponse.yaml + '400': + description: Bad request - Invalid auth method creation parameters + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error400.yaml + '401': + description: Unauthorized - Turnkey stamp is invalid or expired + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error401.yaml + '409': + description: Conflict - Embedded wallet auth method already exists or cannot be created + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error409.yaml + '500': + description: Internal service error + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error500.yaml diff --git a/openapi/paths/embedded-wallets/embedded_wallets_auth_methods_{authMethodId}.yaml b/openapi/paths/embedded-wallets/embedded_wallets_auth_methods_{authMethodId}.yaml new file mode 100644 index 00000000..bca0e246 --- /dev/null +++ b/openapi/paths/embedded-wallets/embedded_wallets_auth_methods_{authMethodId}.yaml @@ -0,0 +1,134 @@ +patch: + summary: Update an embedded wallet auth method + description: | + Update the email address or phone number associated with an embedded wallet + auth method. + + The auth method to update is identified by `authMethodId`, while the + request is authorized with a Turnkey stamp. + operationId: updateEmbeddedWalletAuthMethod + tags: + - Embedded Wallets + security: [] + parameters: + - name: authMethodId + in: path + description: Unique identifier of the embedded wallet auth method to update + required: true + schema: + type: string + example: EmbeddedWalletAuthMethod:019542f5-b3e7-1d02-0000-000000000001 + - name: X-Turnkey-Stamp + in: header + description: > + Turnkey stamp authorizing the request. The stamp may represent either a + session stamp or a direct stamp. + required: true + schema: + type: string + example: stamp:direct:eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9 + requestBody: + required: true + content: + application/json: + schema: + $ref: ../../components/schemas/embedded_wallets/EmbeddedWalletAuthMethodUpdateRequest.yaml + responses: + '200': + description: Embedded wallet auth method updated successfully + content: + application/json: + schema: + $ref: ../../components/schemas/embedded_wallets/EmbeddedWalletAuthOperationResponse.yaml + '400': + description: Bad request - Invalid auth method update parameters + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error400.yaml + '401': + description: Unauthorized - Turnkey stamp is invalid or expired + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error401.yaml + '404': + description: Embedded wallet auth method not found + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error404.yaml + '409': + description: Conflict - Embedded wallet auth method cannot be updated in its current state + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error409.yaml + '500': + description: Internal service error + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error500.yaml + +delete: + summary: Delete an embedded wallet auth method + description: | + Delete an embedded wallet auth method. + + The request will be rejected when the specified auth method is the last + remaining authentication method for the embedded wallet. + operationId: deleteEmbeddedWalletAuthMethod + tags: + - Embedded Wallets + security: [] + parameters: + - name: authMethodId + in: path + description: Unique identifier of the embedded wallet auth method to delete + required: true + schema: + type: string + example: EmbeddedWalletAuthMethod:019542f5-b3e7-1d02-0000-000000000001 + - name: X-Turnkey-Stamp + in: header + description: > + Turnkey stamp authorizing the request. The stamp may represent either a + session stamp or a direct stamp. + required: true + schema: + type: string + example: stamp:session:eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9 + responses: + '204': + description: Embedded wallet auth method deleted successfully + '400': + description: Bad request - Invalid auth method deletion parameters + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error400.yaml + '401': + description: Unauthorized - Turnkey stamp is invalid or expired + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error401.yaml + '404': + description: Embedded wallet auth method not found + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error404.yaml + '409': + description: Conflict - Embedded wallet auth method is the last remaining method or cannot be deleted + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error409.yaml + '500': + description: Internal service error + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error500.yaml diff --git a/openapi/paths/embedded-wallets/embedded_wallets_auth_otp_init.yaml b/openapi/paths/embedded-wallets/embedded_wallets_auth_otp_init.yaml new file mode 100644 index 00000000..109fde36 --- /dev/null +++ b/openapi/paths/embedded-wallets/embedded_wallets_auth_otp_init.yaml @@ -0,0 +1,56 @@ +post: + summary: Initialize an embedded wallet OTP challenge + description: | + Request a one-time password (OTP) challenge for a pending embedded wallet + action. + + This endpoint is used when the next step of the embedded wallet flow + requires OTP verification for authentication or action approval. + operationId: initEmbeddedWalletAuthOtp + tags: + - Embedded Wallets + security: + - BasicAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: ../../components/schemas/embedded_wallets/EmbeddedWalletAuthOtpInitRequest.yaml + responses: + '200': + description: OTP challenge initialized successfully + content: + application/json: + schema: + $ref: ../../components/schemas/embedded_wallets/EmbeddedWalletAuthOperationResponse.yaml + '400': + description: Bad request - Invalid OTP initialization parameters + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error400.yaml + '401': + description: Unauthorized + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error401.yaml + '404': + description: Pending embedded wallet action not found + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error404.yaml + '409': + description: Conflict - OTP challenge is already active or cannot be created + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error409.yaml + '500': + description: Internal service error + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error500.yaml diff --git a/openapi/paths/embedded-wallets/embedded_wallets_auth_otp_verify.yaml b/openapi/paths/embedded-wallets/embedded_wallets_auth_otp_verify.yaml new file mode 100644 index 00000000..565d901b --- /dev/null +++ b/openapi/paths/embedded-wallets/embedded_wallets_auth_otp_verify.yaml @@ -0,0 +1,49 @@ +post: + summary: Verify an embedded wallet OTP challenge + description: | + Verify a previously issued embedded wallet OTP challenge and execute the + pending action associated with that challenge. + + This endpoint does not require partner API credentials. Instead, the OTP + code is supplied in the request body as part of the challenge verification. + operationId: verifyEmbeddedWalletAuthOtp + tags: + - Embedded Wallets + security: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: ../../components/schemas/embedded_wallets/EmbeddedWalletAuthOtpVerifyRequest.yaml + responses: + '200': + description: OTP challenge verified successfully + content: + application/json: + schema: + $ref: ../../components/schemas/embedded_wallets/EmbeddedWalletAuthOperationResponse.yaml + '400': + description: Bad request - Invalid or expired OTP code + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error400.yaml + '404': + description: OTP challenge or pending embedded wallet action not found + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error404.yaml + '409': + description: Conflict - OTP challenge has already been used or cannot be completed + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error409.yaml + '500': + description: Internal service error + content: + application/json: + schema: + $ref: ../../components/schemas/errors/Error500.yaml