Welcome to SnapAuth!

This documentation is for our Server APIs. You can browse our Client API documentation here.

Server APIs are used for finalizing and verifying critical data, such as attaching Credentials to a User Account, and verifying Auth Tokens.

Quick Start

Add a passkey

Done! The passkey is saved and ready for use.

Use a passkey

Done! The response contains information about who just authenticated, so you can start a user session or authorize an action.



cURL must be installed
composer require snapauth/sdk
npm install @snapauth/node-sdk

Install the official SDK from your language's package manager.


# Assuming SNAPAUTH_SECRET_KEY is set; adjust as needed
curl -X 'POST' '' \
     -H 'Content-Type: application/json; charset=utf-8' \
     -u ":$SNAPAUTH_SECRET_KEY" \ # Note the loading colon (:)
     -d '{ JSON body }'


$snapAuthSecret = getenv('SNAPAUTH_SECRET_KEY');
assert($snapAuthSecret !== false);

$snapAuth = new \SnapAuth\Client($snapAuthSecret);
import { SDK } from '@snapauth/node-sdk'

const snapAuth = new SDK(process.env.SNAPAUTH_SECRET_KEY)

We suggest setting API keys through environment variables, as described in the 12-factor app. However, you know your codebase and systems best, so feel free to adjust as needed.


SnapAuth APIs use JSON over HTTPS, which you're likely familar with. The server APIs authenticate using HTTP Basic auth, with a blank username and your secret key as the password.

The only other requirement is adding a Content-type: application/json header.

The endpoint base is and always runs over HTTPS. Never disable certificate verification when using SnapAuth APIs.

Responses follow standard HTTP semantics (2xx/4xx/5xx codes) and return JSON according to our API format. Response formats refer to the contexts of result unless otherwise indicated.


The Registration Server APIs are used after the Client APIs return a one-time use token.

Attach Registration Token

POST /registration/attach

curl -X 'POST' '' \
     -H 'Content-Type: application/json; charset=utf-8' \
     -d $'{
  "token": "rtn_zzz (token from client data)",
  "user": {
    "id": "51123",
    "handle": "ExampleUsername"
$token = $_POST['registrationToken'];

// $user represents a user that either just registered
// or is already signed in.

$result = $snapAuth->attachRegistration($token, [
  'id' => $user->id,
  'handle' => $user->username,
const credential = await snapAuth.attachRegistration(registrationToken, {
  handle: user.handle,
if (credential.ok) {
  // Credential was saved. If desired, persist
} else {

Wrapped Response

  "id": "cdtl_xxx"

This takes the one-time-use registration token from the Client API and associates it with the provided user. A user will not be able to sign in with their new credential until this API is called.

You may store the returned credential identifier, but it's not required.


Name Type Required? Description
token string yes The registration token from the Client SDK
user object yes string yes Your id of the user or entity that this token is associated with. This will be returned to you in authentication APIs.
user.handle string no Your handle of the user or entity that this token is associated with. This is primarily a convenience for authentication to make roundtrips to your backend to look up an id unnecessary.


Name Type Description
id string A Credential identifier. You may store this, but don't have to.


The Authentication Server APIs are used after the Client APIs return a one-time use token.

Verify Authentication Token

POST /auth/verify

curl -X 'POST' '' \
     -H 'Content-Type: application/json; charset=utf-8' \
     -d $'{
  "token": "atn_xxx (token from client data)"
$authToken = $_POST['authToken'];
// Use the user from existing session, other POST data, etc.
$result = $sdk->verifyAuthToken($authToken);

$verifiedUserInfo = $result->user;
// Application-specific logic below, such as Doctrine
$user = $em->find(User::class, $verifiedUserInfo->id);
const auth = await snapAuth.signIn(authToken)
if (auth.ok) {
  const userId =
  // Use this to authenticate the user
} else {

Wrapped Response

  "user": {
    "id": "92372014"

We intend to expose more information about the type and count of factors used during Authentication. We want to get the format right, and would like your feedback about what you need!

Takes a token from the Client Authenticate API and returns the authentication status and metadata.

Use the user section of the response to determine who the token represents in your application.

We strongly recommend using only the id field, but provide both it and the handle (both of the values from Registration) for your convenience.


Name Required? Description
token yes The authentication token from the Client SDK


Name Type Description
user object Information about the authenticated user string The user ID provided during registration

API Format

All of our APIs run over POST requests, in an RPC style, using JSON for requests and responses. Responses will have HTTP codes that work as you would traditionally expect.

Response Wrapping

  "result": {
    // success result, or `null` on error
  "errors": [
    // 0 or more Error objects

The errors key may not be included if there are no errors.

All of our API responses come in a wrapped format

Name Type Description
result object? The wrapped result. Note that response examples will omit this for brevity.
errors? Error[] An array of error structures. Any non-2xx response will have at least one entry.


Error structure

Name Type Description
code ErrorCode A machine-readable error code
message string A human-readable error description

ErrorCode enum

Code Meaning
AuthenticatingUserAccountNotFound The user trying to authenticate is not found. This is most likely to happen if you forget to use the attach token API.
InvalidInput One or more input parameters is invalid
PaymentMethodNeeded The action is restricted due to excessively past-due invoices
PermissionViolation The requested action is not allowed
InternalError An internal error has occurred, or our API is refusing to disclose additional details.

On any unsuccessful request, the errors array will have at least one entry. Successful requests MAY also include errors that represent warnings, deprecations, etc.

HTTP Codes

Code Error Meaning
400 Bad Request Your request is invalid. This may be a bad API key or invalid parameter.
402 Payment Required You need to upgrade to a paid plan, or your organization is significantly behind on payments.
403 Forbidden The action is not allowed.
409 Conflict We've detected a race condition or other conflict.
422 Unprocessable Entity You made a valid request, but reached a limit other than too many requests.
429 Too Many Requests You're making API requests too quickly.
500 Internal Server Error We had a problem with our server. Try again later.