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.comAuthentication
All blocklist endpoints require client authentication via headers:
X-Client-Id: your_client_id
X-Client-Secret: your_client_secret # Only for write operations- Read operations (GET): Require
X-Client-Idonly - Write operations (POST/DELETE): Require both
X-Client-IdandX-Client-Secret
Endpoints
POST /sites/block-user
Block a user from accessing your site.
Authentication: X-Client-Id + X-Client-Secret required
Request:
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:
| Field | Type | Required | Description |
|---|---|---|---|
userId | string (UUID) | Yes | User's unique identifier |
reason | string | No | Reason for blocking (max 500 chars) |
Response: 200 OK
{
"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:
// 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:
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:
| Field | Type | Required | Description |
|---|---|---|---|
userId | string (UUID) | Yes | User's unique identifier |
Response: 200 OK
{
"success": true,
"message": "User unblocked successfully",
"unblockedUser": {
"userId": "550e8400-e29b-41d4-a716-446655440000",
"unblockedAt": "2025-11-05T11:00:00.000Z"
}
}Error Responses:
// 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:
GET /sites/blocked-users?page=1&limit=50
X-Client-Id: flowsta_app_abc123Query Parameters:
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
page | number | No | 1 | Page number (1-indexed) |
limit | number | No | 50 | Results per page (max: 100) |
Response: 200 OK
{
"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:
| Field | Type | Description |
|---|---|---|
userId | string | User's unique identifier |
displayName | string | null | User's display name (if set) |
email | string | Hashed email (for identification) |
did | string | null | Decentralized identifier |
blockedAt | string (ISO 8601) | When user was blocked |
reason | string | null | Reason 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:
GET /sites/check-user-status/550e8400-e29b-41d4-a716-446655440000
X-Client-Id: flowsta_app_abc123URL Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
userId | string (UUID) | Yes | User's unique identifier |
Response: 200 OK (User is blocked)
{
"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)
{
"success": true,
"userId": "550e8400-e29b-41d4-a716-446655440000",
"isBlocked": false,
"blockDetails": null
}Error Responses:
// 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:
GET /sites/stats
X-Client-Id: flowsta_app_abc123Response: 200 OK
{
"success": true,
"stats": {
"totalBlockedUsers": 127,
"blocksLast30Days": 15,
"totalActiveUsers": 5432,
"siteName": "My Awesome App",
"siteId": "770e8400-e29b-41d4-a716-446655440222"
}
}Fields:
| Field | Type | Description |
|---|---|---|
totalBlockedUsers | number | Total users currently blocked |
blocksLast30Days | number | New blocks in last 30 days |
totalActiveUsers | number | Total active users (not blocked) |
siteName | string | Your site/app name |
siteId | string | Your site/app UUID |
Rate Limits
Rate limits are applied per clientId:
| Endpoint | Rate Limit | Window |
|---|---|---|
POST /sites/block-user | 100 requests | per minute |
DELETE /sites/unblock-user | 100 requests | per minute |
GET /sites/blocked-users | 300 requests | per minute |
GET /sites/check-user-status/:userId | 1000 requests | per minute |
GET /sites/stats | 60 requests | per minute |
When rate limit is exceeded:
{
"error": "Rate limit exceeded",
"message": "Too many requests. Please try again later.",
"retryAfter": 60
}Error Codes
| Status Code | Meaning |
|---|---|
200 | Success |
400 | Bad Request - Invalid input |
401 | Unauthorized - Missing or invalid clientId |
403 | Forbidden - Invalid clientSecret or insufficient permissions |
404 | Not Found - Resource doesn't exist |
409 | Conflict - Resource already exists (e.g., user already blocked) |
429 | Too Many Requests - Rate limit exceeded |
500 | Internal Server Error |
Automatic Enforcement
Blocklist checks are automatically enforced during token verification.
When you verify a token with a siteId, Flowsta checks the blocklist:
POST /auth/verify-token
Content-Type: application/json
{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"siteId": "770e8400-e29b-41d4-a716-446655440222"
}Response (user is blocked):
{
"error": "User is blocked from this site",
"valid": false
}Response (user is NOT blocked):
{
"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):
// 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
# 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
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
// ✅ 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 });
});// ❌ BAD - Frontend code
// NEVER do this - exposes secret!
const flowsta = new FlowstaClient({
clientSecret: 'flowsta_secret_abc123' // ❌ EXPOSED!
});Next Steps
- Check SDK Documentation for client library usage
- Review Security Best Practices for security guidelines
- See OAuth Integration for authentication flows
Support
Need help?
- 💬 Discord: Join our community
- 🆘 Support: Find out about Flowsta support options
- 🐙 GitHub: github.com/WeAreFlowsta