Skip to main content
GET
/
api
/
threads
/
{id}
curl -X GET 'http://localhost:5079/api/threads/f47ac10b-58cc-4372-a567-0e02b2c3d479' \
  -H 'Authorization: Bearer YOUR_JWT_TOKEN'
{
  "thread_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "user_id": "user-uuid-here",
  "title": "My Conversation",
  "visibility": "private",
  "created_at": "2024-01-15T10:30:00.000Z",
  "updated_at": "2024-01-15T11:45:00.000Z"
}

Authentication

Conditional (Line 116): [AllowAnonymous] Public sharing enabled: Authentication optional for public/unlisted threads Private threads: Authentication required JWT Claims Extraction (Lines 138-142):
sub | ClaimTypes.NameIdentifier → User UUID (optional for public threads)

Path Parameters

id
string
required
Thread UUIDFormat: Valid GUIDValidation: Route constraint :guid (Line 115)

Response

thread_id
string
UUID identifier
user_id
string
Owner UUID
title
string
Thread title
visibility
string
"private", "public", or "unlisted"
created_at
string
ISO8601 UTC timestamp
updated_at
string
ISO8601 UTC timestamp
curl -X GET 'http://localhost:5079/api/threads/f47ac10b-58cc-4372-a567-0e02b2c3d479' \
  -H 'Authorization: Bearer YOUR_JWT_TOKEN'
{
  "thread_id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "user_id": "user-uuid-here",
  "title": "My Conversation",
  "visibility": "private",
  "created_at": "2024-01-15T10:30:00.000Z",
  "updated_at": "2024-01-15T11:45:00.000Z"
}

Authorization Logic

Feature Flag Check (Line 134):
var publicSharingEnabled = await _systemSettingsService.GetFeatureFlagAsync("public_sharing");
Access Decision Tree (Lines 150-179):
1. Check if public_sharing enabled AND visibility is public/unlisted:
   ├─ TRUE → Allow access (return thread)
   └─ FALSE → Step 2

2. Check if user authenticated:
   ├─ FALSE → 401 UNAUTHORIZED
   └─ TRUE → Step 3

3. Check if visibility is private AND userId != thread.userId:
   ├─ TRUE → 403 FORBIDDEN
   └─ FALSE → Allow access (return thread)

PUBLIC_SHARING Feature Flag States

FlagVisibilityAuthAccess
ONpublicNo✅ Allowed (Line 150-154)
ONunlistedNo✅ Allowed (Line 150-154)
ONprivateNo❌ 401 (Line 158-166)
ONprivateYes (owner)✅ Allowed (Line 179)
ONprivateYes (other)❌ 403 (Line 169-177)
OFFpublicNo❌ 401 (Line 158-166)
OFFpublicYes (owner)✅ Allowed (Line 179)
OFFpublicYes (other)❌ 403 (Line 169-177)
OFFunlistedNo❌ 401
OFFprivateYes (owner)✅ Allowed

Side Effects

Database Reads (Lines 121, 134):
  • SELECT from threads table WHERE thread_id = {id}
  • SELECT from system_settings table WHERE key = 'public_sharing'
No Database Writes: Read-only endpoint

Permissions

Who Can Read:
  1. Public threads (when public_sharing = true): Anyone
  2. Unlisted threads (when public_sharing = true): Anyone with the link
  3. Private threads: Owner only
  4. Any visibility (when public_sharing = false): Owner only
Visibility Semantics:
  • private: Requires auth + ownership
  • public: Visible to all when feature enabled
  • unlisted: Visible to all when feature enabled, but not listed in search/discovery

Edge Cases

  1. Thread doesn’t exist: 404 (Lines 123-131)
  2. Invalid GUID format: 400 (route constraint, not in controller code)
  3. Deleted thread: 404 (service returns null)
  4. Feature flag missing: Treated as false (default behavior assumed)
  5. User ID claim missing for public thread: Allowed (auth optional, Lines 137-142)
  6. User ID claim present but thread private: Ownership check applies (Line 169)

Error Conditions

CodeHTTPCauseController Line
NOT_FOUND404Thread doesn’t exist123-131
UNAUTHORIZED401Auth required but missing158-166
FORBIDDEN403Private thread, wrong user169-177
THREAD_ERROR500Service exception181-189
Exception Handling (Lines 181-189):
catch (Exception ex) {
    return StatusCode(500, new { error = ex.Message, code = "THREAD_ERROR" });
}

Behavioral Guarantees

Visibility Check Order:
  1. Thread existence (404 if not found)
  2. Feature flag + visibility (public access allowed here)
  3. Authentication (401 if required but missing)
  4. Ownership (403 if private + wrong owner)
Authentication Optional: Only for public/unlisted threads with feature flag enabled Ownership Enforcement: Always checked for private threads, regardless of feature flag Feature Flag Dependency: public_sharing setting controls anonymous access

Security Implications

Public Exposure Risk: When public_sharing = true:
  • Public threads visible without authentication
  • Unlisted threads accessible via direct link (URL guessing possible)
  • No rate limiting documented
Privacy Guarantee: Private threads NEVER accessible by non-owners Auth Bypass: Public/unlisted threads accessible anonymously ONLY when feature enabled