NAV
cURL PHP Node

Introduction

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.

Setup

Installation

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

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

Configuration

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

declare(strict_types=1);

$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.

Notes

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 https://api.snapauth.app 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.

Registration

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' 'https://api.snapauth.app/registration/attach' \
     -H 'Content-Type: application/json; charset=utf-8' \
     -u ":$SNAPAUTH_SECRET_KEY" \
     -d $'{
  "token": "rtn_zzz (token from client data)",
  "user": {
    "id": "51123",
    "handle": "ExampleUsername"
  }
}'
<?php
$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, {
  id: user.id,
  handle: user.handle,
})
if (credential.ok) {
  // Credential was saved. If desired, persist credential.result.id
} else {
  console.error(credential.errors)
}

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.

Parameters

Name Type Required? Description
token string yes The registration token from the Client SDK
user object yes
user.id 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.

Response

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

Authentication

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' 'https://api.snapauth.app/auth/verify' \
     -H 'Content-Type: application/json; charset=utf-8' \
     -u ":$SNAPAUTH_SECRET_KEY" \
     -d $'{
  "token": "atn_xxx (token from client data)"
}'
<?php
$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 = auth.result.user.id
  // Use this to authenticate the user
} else {
  console.error(auth.errors)
}

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.

Parameters

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

Response

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

Credential Management

The credential APIs are used to create, manage, and modify Credentials. A User Account can have one or more Credentials, which are used to authenticate.

The credential object

{
  "id": "ctl_xxxxxxx",
  "name": "iCloud Keychain",
  "aaguid": "fbfc3007-154e-4ecc-8c0b-6e020557d7bd",
  "isActive": true,
  "isBackupEligible": true,
  "isBackedUp": true,
  "isUvInitialized": true,
  "transports": [
    "internal",
    "hybrid"
  ]
}
Name Type Description
id string A Credential identifier. You may store this, but don't have to.
name string A user-visible name for the Credential. One will be set automatically by the aaguid when possible.
aaguid string Authenticator Attestation GUID: an identifier for the type of Credential
isActive boolean Whether the Credential can currently be used to sign in
isBackupEligible boolean Whether the Credential can be backed up.
isBackedUp boolean Whether the Credential currently is backed up (as of the most recent authentication).
isUvInitialized boolean Whether the Credential supports User Verification (i.e. 2-factor)
transports AuthenticatorTransport[] What connection mechanisms are supported. Zero or more values from AuthenticatorTransport. Not all clients not provide this data.

Create a Credential

POST /credential/create

curl -X 'POST' 'https://api.snapauth.app/credential/create' \
     -H 'Content-Type: application/json; charset=utf-8' \
     -u ":$SNAPAUTH_SECRET_KEY" \
     -d $'{
  "token": "rtn_abc123",
  "user": {
    "id": "abc123",
    "handle": "user@example.com"
  }
}'

Creates a Credential for a User Account, using a client Registration Token.

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. If you do, you should store it in a one-to-many relationship (one user can have many credential IDs).

We recommend, at minimum, storing a flag that the user has one or more credentials associated with their account

Parameters

Name Type Required? Description
token string yes The registration token from the Client SDK
user object yes
user.id string yes Your primary identifier for 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, such as a username or email address. This is primarily a convenience for authentication to make roundtrips to your backend to look up an id unnecessary.

Returns

A Credential object

Update a Credential

POST /credential/update

curl -X 'POST' 'https://api.snapauth.app/credential/update' \
     -H 'Content-Type: application/json; charset=utf-8' \
     -u ":$SNAPAUTH_SECRET_KEY" \
     -d $'{
  "credentialId": "ctl_xxxxxxx",
  "active": false
}'

Updates an existing credential to match the provided parameters.

Parameters

Name Type Required? Description
credentialId string yes The credential to update
active boolean yes Deactivate (false) or reactivate (true) the credential

A deactivated (active: false) Credential cannot be used to authenticate until reactivated. This is useful primarily if a removable ("roaming") authenticator is lost.

Returns

The updated Credential object

Find Credentials

POST /credential/find

curl -X 'POST' 'https://api.snapauth.app/credential/find' \
     -H 'Content-Type: application/json; charset=utf-8' \
     -u ":$SNAPAUTH_SECRET_KEY" \
     -d $'{
  "user": {
    "handle": "username@example.com"
  }
}'

Wrapped response

{
  "data": [
    {
      "id": "ctl_xxxxxxx",
      // ...
    },
    {
      "id": "ctl_yyyyyyy",
      // ...
    }
  ]
}

Looks up credentials by one or more criteria.

Parameters

Name Type Required? Description
user object Yes Your user information
user.id string Sometimes Your user identifeer
user.handle string Sometimes Your user handle

Either user.id or user.handle is required. Sending both values in the same request is considered an error.

Returns

Returns A list of Credentials matching the provided criteria.

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.

List Responses

{
  "result": {
    "data": [
      { ... },
      { ... },
      { ... }
    ]
  }
}

API responses representing multiple records wrap the values in an object for pagination support.

Name Type Description
data array Zero or more objects of the specified data type

Pagination support will be added in the future.

Enumerations

AuthenticatorTransport

The AuthenticatorTransport enumeration represents the physical layer(s) by which a credential can be used for authentication. This is a direct representation of the W3C WebAuthn format.

Value Meaning
"usb" Removable USB device
"nfc" Near Field Communication (NFC) device
"ble" Bluetooth Low Energy (BLE) device
"smart-card" ISO/IEC 7816 smart card
"hybrid" Mixed transport mechanisms, such as authentication on a desktop by means of a smartphone
"internal" Non-removable platform authenticator

Errors

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.
EntityNotFound
InvalidInput One or more input parameters is invalid
InternalLimitReached
MalformedAuthenticationData
PaymentMethodNeeded The action is restricted due to excessively past-due invoices
PermissionViolation The requested action is not allowed
TokenExpired
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.