---
updatedAt: 2026-09-29T18:19:20.000Z
agentTools:
  projectIndex: https://docs.spinwheel.io/llms.txt
---

# Connect a User via SMS

Connect a User using SMS verification. Identify the user by date of birth, by legal first and last name as it appears on their credit file, or by the last four digits of their Social Security number. One of the three is required. The connection will complete once the user has been verified using the sms verify endpoint. Identification runs on the verify call, so an identity that cannot be resolved is reported there; you may then start a new connect supplying dateOfBirth instead, and nothing in the response indicates whether a date of birth would have resolved it.

<Callout icon="👀" theme="default">
  ### You must capture the [end user's consent](https://docs.spinwheel.io/docs/user-consent) and clearly display the Spinwheel End User Agreement in order to connect the user.
</Callout>

To connect a user via SMS, please provide the following for the user:

* US mobile phone number
* Challenge Data (One of the following challenge data sets at minimum is required. Our standard use case suggestion is using DOB as the challenge data.)
  * Date of birth
  * First/Last Name
  * Last four SSN
* One unique identifier:
  * If it is the first time connecting the user: extUserId
  * If you are connecting an existing user: userId

# OpenAPI definition

```json
{
  "openapi": "3.0.0",
  "paths": {
    "/v1/users/connect/sms": {
      "post": {
        "operationId": "Connect With Sms",
        "summary": "Connect a User via SMS",
        "description": "Connect a User using SMS verification. Identify the user by date of birth, by legal first and last name as it appears on their credit file, or by the last four digits of their Social Security number. One of the three is required. The connection will complete once the user has been verified using the sms verify endpoint. Identification runs on the verify call, so an identity that cannot be resolved is reported there; you may then start a new connect supplying dateOfBirth instead, and nothing in the response indicates whether a date of birth would have resolved it.",
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ConnectSmsRequest"
              },
              "examples": {
                "SMS Connect (legal name instead of date of birth)": {
                  "description": "Connect using the user's legal first and last name in place of a date of birth. Supply the legal name as it appears on the user's credit file. The identity attributes are supplied here, not on the verify call, which continues to take only the passcode.",
                  "value": {
                    "extUserId": "0ae26e20-1413-4291-b6d3-8e033d76728a",
                    "firstName": "Christy",
                    "lastName": "Jenoval",
                    "phoneNumber": "+15555555555"
                  }
                },
                "SMS Connect (SSN last four instead of date of birth)": {
                  "description": "Connect using the last four digits of the user's Social Security number in place of a date of birth or a legal name. The identity attributes are supplied here, not on the verify call, which continues to take only the passcode.",
                  "value": {
                    "extUserId": "0ae26e20-1413-4291-b6d3-8e033d76728a",
                    "ssnLastFourDigits": "1234",
                    "phoneNumber": "+15555555555"
                  }
                },
                "SMS Connect": {
                  "description": "SMS Connect without audit fields",
                  "value": {
                    "extUserId": "0ae26e20-1413-4291-b6d3-8e033d76728a",
                    "dateOfBirth": "1990-01-05",
                    "phoneNumber": "+15555555555"
                  }
                },
                "SMS Connect (with audit fields)": {
                  "description": "SMS Connect with audit fields",
                  "value": {
                    "extUserId": "0ae26e20-1413-4291-b6d3-8e033d76728a",
                    "dateOfBirth": "1990-01-05",
                    "phoneNumber": "+15555555555",
                    "audit": {
                      "consentTimestamp": "2025-03-15T14:30:00Z",
                      "consentType": "WRITTEN",
                      "tosVersion": "v1.0",
                      "tosLanguage": "en"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Success",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectSmsResponse"
                },
                "examples": {
                  "Success": {
                    "value": {
                      "status": {
                        "code": 201,
                        "desc": "success"
                      },
                      "data": {
                        "userId": "52183390-b209-46bd-955b-d6d9d301a84f",
                        "extUserId": "689663dc-077d-4d8c-ac75-5a7c2c305c30",
                        "connectionId": "417f7fa8-81d9-4142-827e-9e9abfeb02df",
                        "connectionStatus": "IN_PROGRESS",
                        "sms": {
                          "codeExpiresAt": 1698357237321,
                          "codeTimeoutSeconds": 300
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad Request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectErrorResponse"
                },
                "examples": {
                  "Invalid Number": {
                    "value": {
                      "status": {
                        "code": 400,
                        "desc": "INVALID_NUMBER",
                        "messages": [
                          {
                            "desc": "The provided phone number is invalid."
                          }
                        ]
                      }
                    }
                  },
                  "Unsupported Number": {
                    "value": {
                      "status": {
                        "code": 400,
                        "desc": "UNSUPPORTED_NUMBER",
                        "messages": [
                          {
                            "desc": "The provided number is not supported. Please utilize the KBA flow to connect."
                          }
                        ]
                      }
                    }
                  },
                  "Unsupported Country Code": {
                    "value": {
                      "status": {
                        "code": 400,
                        "desc": "UNSUPPORTED_COUNTRY_CODE",
                        "messages": [
                          {
                            "desc": "The region associated with the provided phone number is not supported."
                          }
                        ]
                      }
                    }
                  },
                  "Invalid consentTimestamp format": {
                    "value": {
                      "status": {
                        "code": 400,
                        "desc": "Bad Request",
                        "messages": [
                          {
                            "desc": "audit.consentTimestamp must be a UTC RFC 3339 datetime. Ex. 2025-03-15T14:30:00Z",
                            "type": "ERROR"
                          }
                        ]
                      }
                    }
                  },
                  "consentTimestamp older than 24 hours": {
                    "value": {
                      "status": {
                        "code": 400,
                        "desc": "Bad Request",
                        "messages": [
                          {
                            "desc": "audit.consentTimestamp must be a real, parseable UTC datetime within the last 24 hours",
                            "type": "ERROR"
                          }
                        ]
                      }
                    }
                  },
                  "Missing identity attributes": {
                    "value": {
                      "status": {
                        "code": 400,
                        "desc": "Bad Request",
                        "messages": [
                          {
                            "desc": "Provide either dateOfBirth, or both firstName and lastName, or ssnLastFourDigits",
                            "type": "ERROR"
                          }
                        ]
                      }
                    }
                  },
                  "User already connected": {
                    "value": {
                      "status": {
                        "code": 400,
                        "desc": "Bad Request",
                        "messages": [
                          {
                            "desc": "User already connected"
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too Many Requests",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ConnectErrorResponse"
                },
                "examples": {
                  "Too Many Attempts": {
                    "value": {
                      "status": {
                        "code": 429,
                        "desc": "MAX_ATTEMPTS_REACHED",
                        "messages": [
                          {
                            "desc": "Exceeded 5 attempt maximum. Resend a new code in 5 minutes"
                          }
                        ]
                      }
                    }
                  },
                  "Too Many Verifications": {
                    "value": {
                      "status": {
                        "code": 429,
                        "desc": "TOO_MANY_VERIFICATIONS",
                        "messages": [
                          {
                            "desc": "Too many verification attempts - this phone number is disabled for 24hrs."
                          }
                        ]
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "tags": [
          "Connect"
        ],
        "security": [
          {
            "bearerAuth": []
          },
          {
            "bearerAuth": []
          }
        ]
      }
    }
  },
  "info": {
    "title": "Discover",
    "description": "Welcome to Spinwheel's documentation! ",
    "version": "1.0",
    "contact": {}
  },
  "tags": [
    {
      "name": "Connect"
    }
  ],
  "servers": [
    {
      "url": "https://sandbox-api.spinwheel.io"
    },
    {
      "url": "https://api.spinwheel.io"
    },
    {
      "url": "https://secure-api.spinwheel.io"
    },
    {
      "url": "https://secure-sandbox-api.spinwheel.io"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "Authorization",
        "description": "Once you've created a Spinwheel account and received credentials, you can access all of Spinwheel's APIs using a server-to-server call (in order to protect your credentials). When calling an API simply include your secretKey as a bearer token in an auth header like so: \n\n `Authorization: Bearer 8ae8d6fa-df8d-4c5d-9f9b-c4e4c10968b0`"
      }
    },
    "schemas": {
      "Message": {
        "type": "object",
        "properties": {
          "desc": {
            "type": "string",
            "example": "Example status description"
          },
          "type": {
            "enum": [
              "ERROR",
              "WARN",
              "INFO"
            ],
            "type": "string",
            "example": "ERROR"
          }
        },
        "required": [
          "desc"
        ]
      },
      "ResponseStatus": {
        "type": "object",
        "properties": {
          "code": {
            "type": "number",
            "example": 200
          },
          "desc": {
            "type": "string",
            "example": "success"
          },
          "messages": {
            "example": [
              {
                "desc": "Example description"
              }
            ],
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Message"
            }
          }
        }
      },
      "ConnectSmsDetails": {
        "type": "object",
        "properties": {
          "codeExpiresAt": {
            "type": "number",
            "example": 1614602485926,
            "description": "The time the code expires at"
          },
          "codeTimeoutSeconds": {
            "type": "number",
            "example": 300,
            "description": "The length of time, in seconds, until the code expires"
          }
        },
        "required": [
          "codeExpiresAt",
          "codeTimeoutSeconds"
        ]
      },
      "ConnectSmsResponseData": {
        "type": "object",
        "properties": {
          "userId": {
            "type": "string",
            "description": "Id of the user",
            "example": "9226245b-4a4c-48e2-a8cb-9a0e114ed4af"
          },
          "extUserId": {
            "type": "string",
            "description": "A client id registered with Spinwheel on creation",
            "example": "e3119f3a-ac24-4fa8-839b-c9db75848453"
          },
          "connectionId": {
            "type": "string",
            "description": "Id of the connection",
            "example": "e3119f3a-ac24-4fa8-839b-c9db75848453"
          },
          "connectionStatus": {
            "enum": [
              "IN_PROGRESS",
              "SUCCESS",
              "FAILED"
            ],
            "type": "string",
            "description": "connectionStatus",
            "example": "IN_PROGRESS"
          },
          "sms": {
            "$ref": "#/components/schemas/ConnectSmsDetails"
          }
        },
        "required": [
          "userId",
          "extUserId",
          "connectionId",
          "connectionStatus",
          "sms"
        ]
      },
      "ConnectSmsResponse": {
        "type": "object",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/ResponseStatus"
          },
          "data": {
            "$ref": "#/components/schemas/ConnectSmsResponseData"
          }
        },
        "required": [
          "status",
          "data"
        ]
      },
      "AuditRequest": {
        "type": "object",
        "properties": {
          "consentTimestamp": {
            "type": "string",
            "description": "When the user consented to the End User Agreement. Must be a UTC RFC 3339 datetime within the last 24 hours.",
            "example": "2025-03-15T14:30:00Z"
          },
          "tosVersion": {
            "type": "string",
            "description": "Version of the Spinwheel End User Agreement agreed to by the user. Supported versions: v1.0, v1.1.",
            "example": "v1.1",
            "default": "v1.1",
            "enum": [
              "v1.0",
              "v1.1"
            ]
          },
          "tosLanguage": {
            "type": "string",
            "description": "Language in which the Spinwheel End User Agreement was presented. Currently only \"en\" is supported.",
            "example": "en",
            "default": "en",
            "enum": [
              "en"
            ]
          },
          "consentType": {
            "type": "string",
            "description": "How consent was obtained. WRITTEN: written or electronic consent. VERBAL: verbal consent during a recorded interaction.",
            "example": "WRITTEN",
            "enum": [
              "WRITTEN",
              "VERBAL"
            ],
            "default": "WRITTEN"
          }
        }
      },
      "ConnectSmsRequest": {
        "type": "object",
        "properties": {
          "phoneNumber": {
            "type": "string",
            "description": "The phone number in E.164 format.",
            "example": "+14155552671"
          },
          "dateOfBirth": {
            "type": "string",
            "description": "The date of birth. Formatted as YYYY-MM-DD. Supply one of dateOfBirth, firstName + lastName, or ssnLastFourDigits. If more than one is provided, dateOfBirth is used to resolve the identity and the others narrow the match.",
            "example": "2000-01-01"
          },
          "firstName": {
            "type": "string",
            "description": "The user's legal first name, as it appears on their credit file. Must be sent together with lastName. One of dateOfBirth, firstName + lastName, or ssnLastFourDigits is required.",
            "example": "Christy"
          },
          "lastName": {
            "type": "string",
            "description": "The user's legal last name, as it appears on their credit file. Must be sent together with firstName. One of dateOfBirth, firstName + lastName, or ssnLastFourDigits is required.",
            "example": "Jenoval"
          },
          "ssnLastFourDigits": {
            "type": "string",
            "description": "The last four digits of the user's Social Security number. One of dateOfBirth, firstName + lastName, or ssnLastFourDigits is required.",
            "example": "1234"
          },
          "userId": {
            "type": "string",
            "description": "An existing userId to connect with. One of extUserId or userId is required.",
            "example": "7519c55d-68aa-4b21-b580-d70d4fb4f2ab"
          },
          "extUserId": {
            "type": "string",
            "description": "A unique external ID for the user. One of extUserId or userId is required.",
            "example": "1166d9a1-5718-4443-a677-cc40627c5575"
          },
          "audit": {
            "description": "Consent metadata captured at the time of the connect request.",
            "allOf": [
              {
                "$ref": "#/components/schemas/AuditRequest"
              }
            ]
          }
        },
        "required": [
          "phoneNumber",
          "userId",
          "extUserId"
        ]
      },
      "ConnectErrorResponse": {
        "type": "object",
        "properties": {
          "status": {
            "$ref": "#/components/schemas/ResponseStatus"
          }
        },
        "required": [
          "status"
        ]
      }
    }
  }
}
```