Sign in or register with Google

Exchange a Google Identity Services ID token for a Dual session. This one endpoint handles both new and returning users: the first successful request creates a wallet, and later requests sign in to that same wallet. **Client integration:** 1. Configure Google Identity Services with your application's web client ID. 2. Read `credential` from the Google callback. 3. Send that value here as `id_token`. 4. Store the returned access and refresh tokens as you would for any other Dual sign-in method. The `credential` value is a Google **ID token**. Do not send a Google OAuth access token or authorization code. Dual verifies the token's signature, issuer, audience, expiry, stable Google account identifier, and verified email address before issuing a session. Include `organization_id` when the account belongs to a particular organization. Leave it out for an account in the open network scope. The same Google account may have a separate Dual wallet in each scope. A new wallet is active immediately because Google has already verified the email address. Google is never linked to an existing wallet by email alone: if that email belongs to a wallet using another sign-in method, this request returns `409`. Sign in through the existing method instead. No existing Dual session is required — this endpoint creates one.

POST
/auth/provider/google

Request Body

application/json

The Google ID token and, when applicable, the organization to sign in to.

TypeScript Definitions

Use the request body type in TypeScript.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://api.dual.network/auth/provider/google" \  -H "Content-Type: application/json" \  -d '{    "id_token": "<Google ID token>",    "language": "en"  }'
{
  "wallet": {
    "id": "665f1c2d4b1a2c3d4e5f6a01",
    "nickname": "alexf",
    "email": "string",
    "phone_number": "string",
    "avatar": {
      "id": "665f1c2d4b1a2c3d4e5f6a10",
      "name": "string",
      "key": "string",
      "type": "string",
      "url": "string",
      "hash": "string",
      "is_public": true,
      "when_created": "2019-08-24T14:15:22Z"
    },
    "language": "en",
    "fqdn": "string",
    "activated": true,
    "disabled": true,
    "account": {
      "address": "0x1234567890abcdef1234567890abcdef12345678",
      "type": "SMART_WALLET",
      "controller": {
        "address": "string",
        "type": "SECP256K1",
        "custody": "custodial",
        "public_key": "string"
      },
      "smart_account": {
        "chain_id": 1,
        "factory": "string",
        "implementation": "string",
        "index": 0,
        "validator": "string",
        "validator_type": "ECDSA",
        "version": "string"
      }
    },
    "passkey": {
      "credential_id": "string",
      "authenticator_id_hash": "string",
      "pubkey_x": "string",
      "pubkey_y": "string"
    },
    "sessions": [
      {
        "id": "string",
        "permission_id": "string",
        "session_pubkey_x": "string",
        "session_pubkey_y": "string",
        "permissions": {
          "valid_after": "2019-08-24T14:15:22Z",
          "valid_until": "2019-08-24T14:15:22Z",
          "spend_limit": "string",
          "allowed_targets": [
            "string"
          ]
        },
        "valid_until": "2019-08-24T14:15:22Z",
        "status": "active",
        "tx_hash": "string",
        "when_created": "2019-08-24T14:15:22Z"
      }
    ],
    "onboarding": true,
    "when_created": "2019-08-24T14:15:22Z",
    "when_modified": "2019-08-24T14:15:22Z"
  },
  "access_token": "string",
  "refresh_token": "string"
}
{
  "code": 3,
  "message": "Key: 'limit' Error:Field validation for 'limit' failed on the 'lte' tag"
}
{
  "code": 3,
  "message": "limit must be 25 or less",
  "details": {}
}
{
  "code": 3,
  "message": "limit must be 25 or less",
  "details": {}
}
{
  "code": 13,
  "message": "internal error"
}
{
  "code": 3,
  "message": "limit must be 25 or less",
  "details": {}
}