Skip to content

Q&A Web API Documentation

The Q&A Web API provides REST endpoints for the community Q&A system. It enables web interfaces to browse questions, submit answers, vote, and view leaderboards.

Base URL: https://signal.irregulars.io (bot API) or https://qa.irregulars.io (web form)

For protected endpoints, include the API key in the header:

X-Api-Key: <your-api-key>

The Q&A web form at qa.irregulars.io uses OIDC authentication via Authentik:

  1. User clicks “Login”
  2. Redirected to Authentik SSO
  3. After authentication, redirected back with session cookie
  4. Session stored in Cloudflare KV

List questions with filtering and pagination.

ParameterTypeDefaultDescription
querystring-Text search in question content
statusstringopenFilter: open, solved, needs_answer, all
sortstringnewestSort: newest, oldest, most_answers, unanswered
limitnumber50Results per page (max: 100)
offsetnumber0Pagination offset
{
"success": true,
"questions": [
{
"id": "q-1737900123456-abc123",
"question_id": 42,
"question": "How do I configure two-factor authentication?",
"asker": "Alice",
"asker_uuid": "uuid-...",
"group_id": "abc123...",
"group_name": "IrregularChat: Security",
"solved": false,
"answer_count": 2,
"view_count": 15,
"timestamp": "2026-01-25T10:30:00Z",
"created_at": "2026-01-25T10:30:00Z"
}
],
"total": 150,
"offset": 0,
"limit": 50,
"hasMore": true
}

Get a single question with full context including answers, clarifications, and metadata.

ParameterTypeDescription
group_idstringFilter to specific group (optional)
{
"success": true,
"question": {
"id": "q-1737900123456-abc123",
"question_id": 42,
"question": "How do I configure two-factor authentication?",
"asker": "Alice",
"asker_uuid": "uuid-...",
"group_id": "abc123...",
"group_name": "IrregularChat: Security",
"solved": true,
"answer_count": 2,
"view_count": 15,
"timestamp": "2026-01-25T10:30:00Z"
},
"answers": [
{
"answer_id": 1,
"answer": "Go to Settings > Security > Enable 2FA...",
"answerer": "Bob",
"answerer_uuid": "uuid-...",
"is_solution": true,
"status": "accepted",
"upvotes": 5,
"downvotes": 0,
"sources": [
{"url": "https://docs.example.com/2fa"}
],
"confidence_level": 90,
"created_at": "2026-01-25T11:00:00Z"
}
],
"clarifications": [
{
"clarification_id": 1,
"clarification": "Are you asking about app-based or hardware 2FA?",
"author": "Carol",
"created_at": "2026-01-25T10:45:00Z"
}
],
"resources": {
"forum_url": "https://forum.irregularchat.com/t/123",
"breakout_summary": "Discussion concluded with recommendation for TOTP apps"
}
}

Record a question view (for analytics).

{
"viewerUuid": "uuid-...",
"viewerName": "Alice",
"source": "web"
}
{
"success": true
}

Submit an answer to a question.

{
"answer": "Here's how to set up 2FA...",
"answererName": "Bob",
"answererUuid": "uuid-...",
"groupId": "abc123...",
"sources": [
{"url": "https://docs.example.com/2fa"}
],
"confidenceLevel": 85
}
FieldRequiredDescription
answerYesThe answer text
answererNameYesDisplay name of answerer
answererUuidNoUUID for tracking (from OIDC)
groupIdYesGroup ID where question was asked
sourcesNoArray of source URLs
confidenceLevelNo0-100 confidence score
{
"success": true,
"answerId": 5,
"message": "Answer submitted successfully",
"notified": ["Alice", "Carol"]
}

Side Effects:

  • DM notification sent to question asker (if bot is running)
  • DM notification sent to any users who added clarifications

POST /questions/:questionId/answers/:answerId/vote

Section titled “POST /questions/:questionId/answers/:answerId/vote”

Vote on an answer (upvote or downvote).

{
"voteType": "up",
"voterUuid": "uuid-...",
"voterName": "Carol",
"groupId": "abc123..."
}
FieldRequiredDescription
voteTypeYesup or down
voterUuidYesUUID of voter
voterNameNoDisplay name
groupIdYesGroup context
{
"success": true,
"upvotes": 6,
"downvotes": 1,
"score": 5
}

Rules:

  • One vote per user per answer
  • Can change vote (up to down or vice versa)
  • Cannot vote on your own answer

PUT /questions/:questionId/answers/:answerId

Section titled “PUT /questions/:questionId/answers/:answerId”

Edit an existing answer (only by original answerer).

{
"answer": "Updated answer text...",
"editorUuid": "uuid-...",
"editorName": "Bob",
"groupId": "abc123..."
}
{
"success": true
}

Restrictions:

  • Only the original answerer can edit
  • Returns 403 if editorUuid doesn’t match answerer_uuid

POST /questions/:questionId/clarifications

Section titled “POST /questions/:questionId/clarifications”

Add a clarification or follow-up to a question.

{
"clarification": "Are you asking about app-based or hardware 2FA?",
"authorUuid": "uuid-...",
"authorName": "Carol",
"groupId": "abc123..."
}
{
"success": true,
"clarificationId": 3
}

GET /questions/:questionId/answers/:answerId/votes

Section titled “GET /questions/:questionId/answers/:answerId/votes”

Get vote details for a specific answer.

{
"success": true,
"upvotes": 6,
"downvotes": 1,
"voters": [
{"uuid": "uuid-...", "name": "Alice", "vote": "up"},
{"uuid": "uuid-...", "name": "Dave", "vote": "down"}
]
}

Get community leaderboard ranked by helpful answers.

ParameterTypeDefaultDescription
periodstringallTime period: all, month, week
limitnumber50Number of users to return
{
"success": true,
"period": "all",
"updated_at": "2026-01-26T12:00:00Z",
"leaderboard": [
{
"rank": 1,
"uuid": "uuid-...",
"username": "HelpfulBob",
"score": 150,
"solutions_count": 5,
"total_answers": 20,
"acceptance_rate": 25,
"total_upvotes": 45,
"total_downvotes": 2,
"first_answer_at": "2025-06-15T10:00:00Z",
"last_answer_at": "2026-01-25T15:00:00Z",
"badges": ["Top Contributor", "First Place"]
}
],
"total": 42
}
ActionPoints
Solution accepted+25
Upvote received+2
Downvote received-1

Exclusions:

  • Self-answers (answering your own question) don’t count
  • Rejected answers don’t count
BadgeCriteria
Top Contributor10+ solutions
First PlaceRank #1
Second PlaceRank #2
Third PlaceRank #3
Rising Star5+ solutions
Helper1+ solutions

Get a specific user’s leaderboard position.

ParameterTypeDefaultDescription
periodstringallTime period filter
{
"success": true,
"user_rank": {
"rank": 5,
"uuid": "uuid-...",
"username": "Alice",
"score": 75,
"solutions_count": 3,
"total_answers": 12,
"badges": ["Rising Star"]
}
}

If user has no qualifying answers:

{
"success": true,
"user_rank": null,
"message": "User not found on leaderboard (no qualifying answers)"
}

Get a user’s Q&A activity summary.

{
"success": true,
"questions": [
{
"id": "q-...",
"question_id": 42,
"question": "How do I configure 2FA?",
"group_name": "IrregularChat: Security",
"solved": true,
"answer_count": 2,
"created_at": "2026-01-25T10:30:00Z"
}
],
"answers": [
{
"answer_id": 5,
"question_id": 38,
"answer": "You can find that in settings...",
"group_name": "IrregularChat: Help",
"is_solution": true,
"upvotes": 3,
"created_at": "2026-01-24T14:00:00Z"
}
],
"stats": {
"questions_asked": 5,
"answers_given": 12,
"solutions": 3,
"total_upvotes": 25
}
}

Search wiki articles using semantic search (OpenAI embeddings).

ParameterTypeDefaultDescription
qstringrequiredSearch query (min 3 characters)
limitnumber5Results limit (max: 10)
{
"success": true,
"query": "two factor authentication",
"results": [
{
"title": "Security Best Practices",
"url": "https://wiki.irregularchat.com/security",
"category": "Security",
"tags": ["2fa", "authentication"],
"similarity": 0.89,
"excerpt": "Two-factor authentication (2FA) adds an extra layer..."
}
]
}

All endpoints return consistent error format:

{
"success": false,
"error": "Error message description"
}
CodeMeaning
200Success
400Bad request (missing/invalid parameters)
401Unauthorized (invalid API key)
403Forbidden (e.g., editing another user’s answer)
404Not found (question/answer doesn’t exist)
500Server error
503Database not initialized

The web interface at qa.irregulars.io provides:

  • / - Homepage with recent questions
  • /q/:id - View question with answers
  • /leaderboard - Community rankings
  • /account - User’s questions and answers
  • Answer submission forms
  • Voting on answers
  • Adding clarifications
  1. Click “Login” button
  2. Redirect to Authentik SSO (sso.irregularchat.com)
  3. Authenticate with IrregularChat account
  4. Redirect back to Q&A with session
  5. Session stored in Cloudflare KV (24-hour expiry)

The web form requires these OIDC endpoints:

SettingDescription
OIDC_ISSUERAuthentik issuer URL
OIDC_AUTHORIZATION_URLOAuth authorize endpoint
OIDC_TOKEN_URLOAuth token endpoint
OIDC_USERINFO_URLUser info endpoint
OIDC_LOGOUT_URLLogout endpoint
OIDC_CLIENT_IDOAuth client ID
OIDC_CLIENT_SECRETOAuth client secret (set as Cloudflare secret)

  1. Signal → User sends !ask How do I...?
  2. Bot → Saves question to PostgreSQL
  3. Web → Question appears at qa.irregulars.io
  4. Web → User submits answer via form
  5. Bot → Sends DM notification to original asker
  6. Signal → Asker can !accept or !reject the answer
Web ActionSignal Command
View question!question ABC123
Submit answer!answer ABC123 <text>
UpvoteNo equivalent (web only)
Add clarification!clarify ABC123 <text>
Mark solved!accept ABC123 A1

Terminal window
curl "https://signal.irregulars.io/questions?status=open&limit=10"
Terminal window
curl "https://signal.irregulars.io/questions?query=vpn&status=all"
Terminal window
curl -X POST "https://signal.irregulars.io/questions/42/answers" \
-H "Content-Type: application/json" \
-H "X-Api-Key: YOUR_API_KEY" \
-d '{
"answer": "Here is how to configure VPN...",
"answererName": "Bob",
"answererUuid": "uuid-...",
"groupId": "abc123..."
}'
Terminal window
curl "https://signal.irregulars.io/leaderboard?period=month&limit=10"

  • Added view tracking endpoint (POST /questions/:id/view)
  • Added confidence level to answers
  • Added sources array for citations
  • Wiki semantic search integration