Skip to content

Site Blocklist API

DEPRECATED

This API is deprecated as of SDK 2.0. Flowsta now uses OAuth 2.0 with PKCE exclusively, which does not support client secrets.

Alternative: Implement user blocking/banning in your own application database. Most applications handle access control at the application level rather than at the authentication provider level.

Migration: If your application currently uses this API, you'll need to implement your own user access control system in your application's backend.

Complete API reference for Site Blocklist Management endpoints.

Base URL

Production: https://auth-api.flowsta.com
Staging:    https://auth-api-staging.flowsta.com

Authentication

All blocklist endpoints require client authentication via headers:

http
X-Client-Id: your_client_id
X-Client-Secret: your_client_secret  # Only for write operations
  • Read operations (GET): Require X-Client-Id only
  • Write operations (POST/DELETE): Require both X-Client-Id and X-Client-Secret

Endpoints

POST /sites/block-user

Block a user from accessing your site.

Authentication: X-Client-Id + X-Client-Secret required

Request:

http
POST /sites/block-user
Content-Type: application/json
X-Client-Id: flowsta_app_abc123
X-Client-Secret: your_secret_here

{
  "userId": "550e8400-e29b-41d4-a716-446655440000",
  "reason": "Violation of community guidelines"
}

Parameters:

FieldTypeRequiredDescription
userIdstring (UUID)YesUser's unique identifier
reasonstringNoReason for blocking (max 500 chars)

Response: 200 OK

json
{
  "success": true,
  "message": "User blocked successfully",
  "blockedUser": {
    "userId": "550e8400-e29b-41d4-a716-446655440000",
    "blockedAt": "2025-11-05T10:30:00.000Z",
    "reason": "Violation of community guidelines"
  }
}

Error Responses:

json
// 404 Not Found - User doesn't exist
{
  "error": "User not found",
  "message": "The specified user does not exist"
}

// 409 Conflict - User already blocked
{
  "error": "User already blocked",
  "message": "This user is already blocked from your site"
}

// 401 Unauthorized - Missing or invalid credentials
{
  "error": "Invalid client secret",
  "message": "The provided client secret is incorrect"
}

DELETE /sites/unblock-user

Remove a user from your site's blocklist.

Authentication: X-Client-Id + X-Client-Secret required

Request:

http
DELETE /sites/unblock-user
Content-Type: application/json
X-Client-Id: flowsta_app_abc123
X-Client-Secret: your_secret_here

{
  "userId": "550e8400-e29b-41d4-a716-446655440000"
}

Parameters:

FieldTypeRequiredDescription
userIdstring (UUID)YesUser's unique identifier

Response: 200 OK

json
{
  "success": true,
  "message": "User unblocked successfully",
  "unblockedUser": {
    "userId": "550e8400-e29b-41d4-a716-446655440000",
    "unblockedAt": "2025-11-05T11:00:00.000Z"
  }
}

Error Responses:

json
// 404 Not Found - User not in blocklist
{
  "error": "User not blocked",
  "message": "This user is not in your blocklist"
}

GET /sites/blocked-users

Get paginated list of all blocked users for your site.

Authentication: X-Client-Id required (read operation)

Request:

http
GET /sites/blocked-users?page=1&limit=50
X-Client-Id: flowsta_app_abc123

Query Parameters:

ParameterTypeRequiredDefaultDescription
pagenumberNo1Page number (1-indexed)
limitnumberNo50Results per page (max: 100)

Response: 200 OK

json
{
  "success": true,
  "blockedUsers": [
    {
      "userId": "550e8400-e29b-41d4-a716-446655440000",
      "displayName": "John Doe",
      "email": "a1b2c3d4e5f6...",
      "did": "did:flowsta:uhCAkSomeAgentPubKeyHash",
      "blockedAt": "2025-11-05T10:30:00.000Z",
      "reason": "Violation of community guidelines"
    },
    {
      "userId": "660e8400-e29b-41d4-a716-446655440111",
      "displayName": "Jane Smith",
      "email": "d4e5f6g7h8i9...",
      "did": "did:flowsta:uhCAkAnotherAgentPubKeyHash",
      "blockedAt": "2025-11-04T15:20:00.000Z",
      "reason": "Spam posting"
    }
  ],
  "pagination": {
    "page": 1,
    "limit": 50,
    "totalBlocked": 127,
    "totalPages": 3,
    "hasMore": true
  }
}

Fields:

FieldTypeDescription
userIdstringUser's unique identifier
displayNamestring | nullUser's display name (if set)
emailstringHashed email (for identification)
didstring | nullDecentralized identifier
blockedAtstring (ISO 8601)When user was blocked
reasonstring | nullReason for blocking

GET /sites/check-user-status/:userId

Check if a specific user is blocked from your site.

Authentication: X-Client-Id required (read operation)

Request:

http
GET /sites/check-user-status/550e8400-e29b-41d4-a716-446655440000
X-Client-Id: flowsta_app_abc123

URL Parameters:

ParameterTypeRequiredDescription
userIdstring (UUID)YesUser's unique identifier

Response: 200 OK (User is blocked)

json
{
  "success": true,
  "userId": "550e8400-e29b-41d4-a716-446655440000",
  "isBlocked": true,
  "blockDetails": {
    "blockedAt": "2025-11-05T10:30:00.000Z",
    "reason": "Violation of community guidelines"
  }
}

Response: 200 OK (User is NOT blocked)

json
{
  "success": true,
  "userId": "550e8400-e29b-41d4-a716-446655440000",
  "isBlocked": false,
  "blockDetails": null
}

Error Responses:

json
// 400 Bad Request - Invalid UUID format
{
  "error": "Invalid user ID format",
  "message": "User ID must be a valid UUID"
}

GET /sites/stats

Get statistics about your site's blocklist and users.

Authentication: X-Client-Id required (read operation)

Request:

http
GET /sites/stats
X-Client-Id: flowsta_app_abc123

Response: 200 OK

json
{
  "success": true,
  "stats": {
    "totalBlockedUsers": 127,
    "blocksLast30Days": 15,
    "totalActiveUsers": 5432,
    "siteName": "My Awesome App",
    "siteId": "770e8400-e29b-41d4-a716-446655440222"
  }
}

Fields:

FieldTypeDescription
totalBlockedUsersnumberTotal users currently blocked
blocksLast30DaysnumberNew blocks in last 30 days
totalActiveUsersnumberTotal active users (not blocked)
siteNamestringYour site/app name
siteIdstringYour site/app UUID

Rate Limits

Rate limits are applied per clientId:

EndpointRate LimitWindow
POST /sites/block-user100 requestsper minute
DELETE /sites/unblock-user100 requestsper minute
GET /sites/blocked-users300 requestsper minute
GET /sites/check-user-status/:userId1000 requestsper minute
GET /sites/stats60 requestsper minute

When rate limit is exceeded:

json
{
  "error": "Rate limit exceeded",
  "message": "Too many requests. Please try again later.",
  "retryAfter": 60
}

Error Codes

Status CodeMeaning
200Success
400Bad Request - Invalid input
401Unauthorized - Missing or invalid clientId
403Forbidden - Invalid clientSecret or insufficient permissions
404Not Found - Resource doesn't exist
409Conflict - Resource already exists (e.g., user already blocked)
429Too Many Requests - Rate limit exceeded
500Internal Server Error

Automatic Enforcement

Blocklist checks are automatically enforced during token verification.

When you verify a token with a siteId, Flowsta checks the blocklist:

http
POST /auth/verify-token
Content-Type: application/json

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "siteId": "770e8400-e29b-41d4-a716-446655440222"
}

Response (user is blocked):

json
{
  "error": "User is blocked from this site",
  "valid": false
}

Response (user is NOT blocked):

json
{
  "valid": true,
  "user": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "email": "user@example.com",
    "agentPubKey": "uhCAk..."
  }
}

Code Examples

JavaScript / Node.js

Server-side API calls (client secret required):

javascript
// Block a user
async function blockUser(userId, reason) {
  const response = await fetch('https://auth-api.flowsta.com/sites/block-user', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'X-Client-Id': process.env.FLOWSTA_CLIENT_ID,
      'X-Client-Secret': process.env.FLOWSTA_CLIENT_SECRET
    },
    body: JSON.stringify({
      userId,
      reason
    })
  });

  if (!response.ok) {
    throw new Error(`Failed to block user: ${response.statusText}`);
  }

  return await response.json();
}

// Get blocked users
async function getBlockedUsers(page = 1, limit = 50) {
  const response = await fetch(
    `https://auth-api.flowsta.com/sites/blocked-users?page=${page}&limit=${limit}`,
    {
      headers: {
        'X-Client-Id': process.env.FLOWSTA_CLIENT_ID,
        'X-Client-Secret': process.env.FLOWSTA_CLIENT_SECRET
      }
    }
  );

  if (!response.ok) {
    throw new Error(`Failed to get blocked users: ${response.statusText}`);
  }

  return await response.json();
}

// Usage
await blockUser('550e8400-e29b-41d4-a716-446655440000', 'Violation of ToS');
const { blockedUsers, pagination } = await getBlockedUsers(1, 50);

Server-Side Only

The Site Blocklist API requires a client secret and must be called from your backend server. Never expose your client secret in frontend code.

cURL

bash
# Block a user
curl -X POST https://auth-api.flowsta.com/sites/block-user \
  -H "Content-Type: application/json" \
  -H "X-Client-Id: flowsta_app_abc123" \
  -H "X-Client-Secret: your_secret_here" \
  -d '{
    "userId": "550e8400-e29b-41d4-a716-446655440000",
    "reason": "Spam posting"
  }'

# Get blocked users
curl https://auth-api.flowsta.com/sites/blocked-users?page=1&limit=50 \
  -H "X-Client-Id: flowsta_app_abc123"

# Check user status
curl https://auth-api.flowsta.com/sites/check-user-status/550e8400-e29b-41d4-a716-446655440000 \
  -H "X-Client-Id: flowsta_app_abc123"

Python

python
import requests

BASE_URL = "https://auth-api.flowsta.com"
CLIENT_ID = "flowsta_app_abc123"
CLIENT_SECRET = "your_secret_here"

# Block a user
response = requests.post(
    f"{BASE_URL}/sites/block-user",
    headers={
        "Content-Type": "application/json",
        "X-Client-Id": CLIENT_ID,
        "X-Client-Secret": CLIENT_SECRET
    },
    json={
        "userId": "550e8400-e29b-41d4-a716-446655440000",
        "reason": "Violation of community guidelines"
    }
)

result = response.json()
print(f"Blocked: {result['success']}")

Security Considerations

Never Expose Client Secret

⚠️ Critical: Your client secret must NEVER be exposed in:

  • Frontend JavaScript code
  • Mobile app binaries
  • Public repositories
  • Client-side storage

Always use server-side code for write operations (block/unblock).

Server-Side Example

javascript
// ✅ GOOD - Backend route
app.post('/api/admin/block-user', requireAdmin, async (req, res) => {
  const { userId, reason } = req.body;
  
  // Server-side call with secret
  await flowsta.blockUser({ userId, reason });
  
  res.json({ success: true });
});
javascript
// ❌ BAD - Frontend code
// NEVER do this - exposes secret!
const flowsta = new FlowstaClient({
  clientSecret: 'flowsta_secret_abc123' // ❌ EXPOSED!
});

Next Steps

Support

Need help?

Documentation licensed under CC BY-SA 4.0.