API Documentation

Complete REST API for managing sites, users, and authentication sessions. Build powerful integrations with Signin.fast's authentication platform.

ℹ️

API Not Required for Basic Integration

You don't need this API to integrate Signin.fast with your site. Our standard integration works with simple redirects and callbacks - no API calls required!

This API is for advanced use cases:

• Programmatically managing your user data

• Onboarding existing users into Signin.fast

• Building custom dashboards and analytics

• Exporting or migrating your user data

Quick Start

Get your API token from your account dashboard and start making requests:

curl -H "Authorization: Bearer YOUR_API_TOKEN" \ https://signin.fast/api/sites

Authentication

All API requests require authentication using a Bearer token. You can find your API token in your account dashboard.

# Include your API token in the Authorization header Authorization: Bearer YOUR_API_TOKEN # Example request curl -H "Authorization: Bearer gma_dev_token" \ https://signin.fast/api/sites

Security Notes

  • Keep your API token secure and never expose it in client-side code
  • All API requests are made over HTTPS
  • API tokens are scoped to your account - you can only access your own data
  • Tokens do not expire but can be regenerated in your dashboard

Embed Widget Integration

The easiest way to integrate Signin.fast is with our JavaScript embed widget. No API calls required!

🚀

Recommended Integration Method

Use the embed widget for most integrations. It provides a clean modal interface that works with any website and handles all authentication flows automatically.

Benefits of the embed widget:

• No backend integration required

• Clean modal interface that doesn't navigate away

• Works with React, Vue, and any JavaScript framework

• Automatic CSRF protection and security

• Mobile responsive design

Basic Integration

Add one script tag to your website. No visible UI is added until triggered:

<script src="https://signin.fast/your-site-slug/embed.js"></script> <!-- Trigger buttons (automatically bound) --> <button data-signin-fast="login">Login</button> <button data-signin-fast="signup">Sign Up</button>

Programmatic Control

Use these JavaScript methods when you want to control the modal flow yourself, without using the automatic data attributes or CSS class approach:

💡

When to Use Programmatic Control

Most integrations don't need this. The widget automatically binds to elements with data-signin-fast attributes or CSS classes like .signin-fast-login.

Use programmatic control when you need to:

• Trigger authentication from custom JavaScript logic

• Integrate with complex UI frameworks or state management

• Control modal timing based on user interactions

• Handle authentication within existing event handlers

// Open to specific tabs SigninFast.openModalToLogin(); SigninFast.openModalToSignup(); SigninFast.openModalToResetPassword(); // Generic open (defaults to login) SigninFast.openModal(); // Close modal SigninFast.closeModal(); // Listen for authentication events window.addEventListener('signinFastAuth', function(event) { console.log('User authenticated:', event.detail); // event.detail contains: action, user, success, token if (event.detail.success) { // Handle successful login/signup window.location.href = '/dashboard'; } });

Authentication Flow & Callback Handling

After successful authentication via the embed widget, users are redirected to your site's callback URL with an authentication token.

Callback URL Setup

Configure your success callback URL in your site settings (e.g., https://yoursite.com/auth/callback). After authentication, users will be redirected to:

https://yoursite.com/auth/callback?token=tkn_abc123

Token Exchange

Exchange the token for user information on your backend:

// Backend code to exchange token for user data const token = req.query.token; // Extract from callback URL // Make API request to get user info const response = await fetch(`https://signin.fast/api/site_user_sessions/${token}`, { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_TOKEN', 'Content-Type': 'application/json' } }); const userData = await response.json(); // userData contains: { site_user: { email: "user@example.com", ... } } // Mark token as used for security await fetch(`https://signin.fast/api/site_user_sessions/${token}/mark_used`, { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_TOKEN', 'Content-Type': 'application/json' } });

Complete Flow Example

// 1. User clicks widget trigger // 2. Widget opens modal // 3. User signs in/up // 4. Widget closes and user is redirected to: // https://yoursite.com/auth/callback?token=tkn_abc123 // 5. Your backend handles the callback: app.get('/auth/callback', async (req, res) => { const { token } = req.query; if (!token) { return res.redirect('/login?error=no_token'); } try { // Exchange token for user data const response = await fetch(`https://signin.fast/api/site_user_sessions/${token}`, { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_TOKEN', 'Content-Type': 'application/json' } }); const { site_user } = await response.json(); // Mark token as used await fetch(`https://signin.fast/api/site_user_sessions/${token}/mark_used`, { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_TOKEN', 'Content-Type': 'application/json' } }); // Create session, set cookies, etc. req.session.user = site_user; // Redirect to protected area res.redirect('/dashboard'); } catch (error) { console.error('Auth error:', error); res.redirect('/login?error=auth_failed'); } });
🔐

Security Best Practices

Always exchange tokens on your backend - Never expose API tokens to the client

Mark tokens as used immediately - Prevents replay attacks

Validate tokens server-side - Don't trust client-side authentication

Handle token expiration - Tokens are valid for a limited time

React Integration

Use the embed widget in React applications:

import React, { useEffect, useState } from 'react'; function AuthComponent() { const [user, setUser] = useState(null); useEffect(() => { // Load the embed script const script = document.createElement('script'); script.src = 'https://signin.fast/your-site-slug/embed.js'; document.head.appendChild(script); // Listen for authentication events const handleAuth = (event) => { if (event.detail.success) { setUser(event.detail.user); // Update your app state, make API calls, etc. } }; window.addEventListener('signinFastAuth', handleAuth); return () => { window.removeEventListener('signinFastAuth', handleAuth); document.head.removeChild(script); }; }, []); const handleLogin = () => { if (window.SigninFast) { window.SigninFast.openModalToLogin(); } }; const handleSignup = () => { if (window.SigninFast) { window.SigninFast.openModalToSignup(); } }; return ( <div> {user ? ( <p>Welcome, {user.email}!</p> ) : ( <div> <button onClick={handleLogin}>Login</button> <button onClick={handleSignup}>Sign Up</button> </div> )} </div> ); } export default AuthComponent;

Vue.js Integration

Use the embed widget in Vue applications:

<template> <div> <div v-if="user"> <p>Welcome, {{ user.email }}!</p> </div> <div v-else> <button @click="openLogin">Login</button> <button @click="openSignup">Sign Up</button> </div> </div> </template> <script> import { ref, onMounted, onUnmounted } from 'vue'; export default { name: 'AuthComponent', setup() { const user = ref(null); let script = null; const handleAuth = (event) => { if (event.detail.success) { user.value = event.detail.user; // Update your app state, call your API, etc. } }; const openLogin = () => { if (window.SigninFast) { window.SigninFast.openModalToLogin(); } }; const openSignup = () => { if (window.SigninFast) { window.SigninFast.openModalToSignup(); } }; onMounted(() => { // Load the embed script script = document.createElement('script'); script.src = 'https://signin.fast/your-site-slug/embed.js'; document.head.appendChild(script); // Listen for authentication events window.addEventListener('signinFastAuth', handleAuth); }); onUnmounted(() => { if (script) { window.removeEventListener('signinFastAuth', handleAuth); document.head.removeChild(script); } }); return { user, openLogin, openSignup }; } }; </script>

Framework Compatibility

The widget automatically works with:

  • Turbo (Rails 7+): Automatically re-binds after navigation
  • htmx: Automatically detects content swaps
  • React/Vue/Angular: Works with all modern frameworks
  • Dynamic Content: Uses MutationObserver to detect new elements

Custom Styling

Override widget styles to match your brand:

/* Custom button styling */ .signin-fast-button { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%) !important; border-radius: 30px !important; } /* Custom modal styling */ .signin-fast-content { border-radius: 20px !important; box-shadow: 0 25px 80px rgba(0,0,0,0.3) !important; }
📖

Complete Documentation

For complete embed widget documentation, examples, and advanced configuration options, visit our Embed Widget Documentation.

Sites API

Manage your authentication sites programmatically.

GET /api/sites Authenticated

Retrieve a list of all sites in your account.

Query Parameters

Parameter Type Required Description
search string optional Search sites by name
slug string optional Filter by specific slug

Example Response

{ "sites": [ { "id": 1, "name": "My App", "slug": "my-app", "home_uri": "https://myapp.com", "success_uri": "https://myapp.com/auth/callback", "cancel_uri": "https://myapp.com/auth/cancel", "failed_uri": "https://myapp.com/auth/failed", "client_id": "pid_abc123", "client_secret": "pst_secret123", "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-01T00:00:00Z" } ] }
POST /api/sites Authenticated

Create a new site in your account.

Request Body

{ "site": { "name": "My New App", "slug": "my-new-app", "home_uri": "https://mynewapp.com", "success_uri": "https://mynewapp.com/auth/success" } }

Site Users API

Manage users across your sites with full CRUD operations.

GET /api/site_users Authenticated

Retrieve a paginated list of users across all sites or filtered by specific site.

Query Parameters

Parameter Type Required Description
site_id integer optional Filter users by specific site
search string optional Search users by email
page integer optional Page number (default: 1)
per_page integer optional Items per page (default: 25, max: 100)
POST /api/site_users Authenticated

Create a new user for a specific site.

Request Body

{ "site_id": 1, "site_user": { "email": "user@example.com", "password": "secure_password", "name": "John Doe" } }

Site User Sessions API

Manage authentication sessions and track user login activity.

GET /api/site_user_sessions Authenticated

Retrieve authentication sessions with flexible filtering options.

Query Parameters

Parameter Type Required Description
site_user_id integer optional Filter by specific user
site_id integer optional Filter by specific site
used boolean optional Filter by session usage status
POST /api/site_user_sessions/:id/mark_used Authenticated

Mark a session as used for security tracking.

Example Response

{ "site_user_session": { "id": 123, "token": "tkn_abc123", "used": true, "created_at": "2024-01-01T12:00:00Z" }, "message": "Session marked as used" }

Error Handling

The API returns appropriate HTTP status codes and detailed error messages.

HTTP Status Codes

Status Code Description
200 Success
201 Created
400 Bad Request
401 Unauthorized
404 Not Found
422 Unprocessable Entity

Error Response Format

{ "error": "Validation failed", "messages": [ "Email can't be blank", "Password is too short" ] }

Code Examples

JavaScript/Node.js

// Using fetch API const response = await fetch('https://signin.fast/api/sites', { headers: { 'Authorization': 'Bearer YOUR_API_TOKEN', 'Content-Type': 'application/json' } }); const data = await response.json(); console.log(data.sites);

Python

import requests headers = { 'Authorization': 'Bearer YOUR_API_TOKEN', 'Content-Type': 'application/json' } response = requests.get('https://signin.fast/api/sites', headers=headers) sites = response.json()['sites']

Ruby

require 'httparty' headers = { 'Authorization' => 'Bearer YOUR_API_TOKEN', 'Content-Type' => 'application/json' } response = HTTParty.get('https://signin.fast/api/sites', headers: headers) sites = response.parsed_response['sites']