Skip to main content

Recommendation Feedback

The PlaySync platform allows clients to provide feedback on recommendations, enabling a feedback loop that improves the user experience by preventing repetitive recommendations and tracking user preferences.

Overview

When users receive recommendations, they can respond with either "accept" or "reject" feedback. This feedback is stored and used to:

  • Prevent repetitive recommendations - Users won't see the same candidates repeatedly
  • Track user preferences - Build a history of user decisions
  • Improve user experience - Reduce recommendation fatigue
  • Enable analytics - Understand which recommendations are effective

Providing Feedback on Recommendations

Record Feedback

To provide feedback on a recommendation, make a POST request to the /v1/users/{user_id}/recommendations/feedback endpoint.

Request:

curl -X POST \
"https://api.playsync.com/v1/users/user123/recommendations/feedback" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"candidate_id": "user456",
"response": "accept"
}'

Response:

{
"message": "Recommendation feedback recorded successfully"
}

Request Body Parameters

  • candidate_id (required): The ID of the recommended user that the feedback is for
  • response (required): Either "accept" or "reject"

Example - Rejecting a recommendation:

curl -X POST \
"https://api.playsync.com/v1/users/user123/recommendations/feedback" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"candidate_id": "user789",
"response": "reject"
}'

Getting Feedback History

Retrieve User's Feedback History

To get a user's complete feedback history, make a GET request to the /v1/users/{user_id}/recommendations/feedback endpoint.

Request:

curl -X GET \
"https://api.playsync.com/v1/users/user123/recommendations/feedback" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Response:

{
"feedbacks": [
{
"id": 1,
"platform_id": "client123",
"user_id": "user123",
"candidate_id": "user456",
"response": "accept",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z"
},
{
"id": 2,
"platform_id": "client123",
"user_id": "user123",
"candidate_id": "user789",
"response": "reject",
"created_at": "2024-01-15T11:45:00Z",
"updated_at": "2024-01-15T11:45:00Z"
}
]
}

How Feedback Affects Recommendations

Automatic Exclusion

Once a user provides feedback on a recommendation (either accept or reject), that candidate will be automatically excluded from future recommendations for that user.

Example Flow:

  1. User receives recommendations: [userA, userB, userC, userD]
  2. User provides feedback:
    • Accepts userA
    • Rejects userB
  3. Next time user requests recommendations, userA and userB will be excluded
  4. New recommendations: [userE, userF, userG, userH]

Feedback Updates

You can update feedback for the same candidate by making another POST request. The system will update the existing feedback record.

# Update feedback from "reject" to "accept"
curl -X POST \
"https://api.playsync.com/v1/users/user123/recommendations/feedback" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"candidate_id": "user789",
"response": "accept"
}'

Complete Recommendation Feedback Flow

Here's a complete example of how to implement recommendation feedback in your application:

# 1. Get recommendations for a user
curl -X GET "https://api.playsync.com/v1/users/user123/recommendations?count=5" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# Response contains recommendations
{
"recommendations": [
{
"client_user_id": "user456",
"display_name": "PlayerTwo",
"overall_score": 0.85
},
{
"client_user_id": "user789",
"display_name": "PlayerThree",
"overall_score": 0.72
}
]
}

# 2. User accepts first recommendation
curl -X POST "https://api.playsync.com/v1/users/user123/recommendations/feedback" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"candidate_id": "user456",
"response": "accept"
}'

# 3. User rejects second recommendation
curl -X POST "https://api.playsync.com/v1/users/user123/recommendations/feedback" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"candidate_id": "user789",
"response": "reject"
}'

# 4. Get new recommendations (user456 and user789 will be excluded)
curl -X GET "https://api.playsync.com/v1/users/user123/recommendations?count=5" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

# 5. Check feedback history
curl -X GET "https://api.playsync.com/v1/users/user123/recommendations/feedback" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Error Handling

Common Error Responses

Invalid response value:

{
"error": "Bad Request",
"message": "response must be either 'accept' or 'reject'"
}

Missing candidate_id:

{
"error": "Bad Request",
"message": "candidate_id is required"
}

User not found:

{
"error": "Not Found",
"message": "User with ID 'user123' does not exist"
}

Unauthorized:

{
"error": "Unauthorized",
"message": "Missing or invalid authentication token"
}

Best Practices

(This part needs more work)

1. Collect Feedback Promptly

Provide feedback as soon as users interact with recommendations to maintain accurate exclusion lists.

2. Handle Both Accept and Reject

Even if your UI only shows "accept" actions, consider tracking implicit rejects (e.g., when users ignore recommendations).

3. Update Feedback When Needed

Allow users to change their mind by updating feedback when appropriate.

4. Monitor Feedback Patterns

Use the feedback history endpoint to analyze user preferences and improve your recommendation UI.

5. Implement Fallback Logic

Handle cases where users have provided feedback on many candidates and fewer new recommendations are available.

Integration Examples

JavaScript/Node.js Example

class RecommendationManager {
constructor(accessToken) {
this.accessToken = accessToken;
this.baseUrl = 'https://api.playsync.com';
}

async getRecommendations(userId, count = 10) {
const response = await fetch(
`${this.baseUrl}/v1/users/${userId}/recommendations?count=${count}`,
{
headers: {
'Authorization': `Bearer ${this.accessToken}`
}
}
);
return response.json();
}

async provideFeedback(userId, candidateId, response) {
const response = await fetch(
`${this.baseUrl}/v1/users/${userId}/recommendations/feedback`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${this.accessToken}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
candidate_id: candidateId,
response: response
})
}
);
return response.json();
}

async getFeedbackHistory(userId) {
const response = await fetch(
`${this.baseUrl}/v1/users/${userId}/recommendations/feedback`,
{
headers: {
'Authorization': `Bearer ${this.accessToken}`
}
}
);
return response.json();
}
}

// Usage
const manager = new RecommendationManager('your-access-token');

// Get recommendations
const recommendations = await manager.getRecommendations('user123', 5);

// User accepts a recommendation
await manager.provideFeedback('user123', 'user456', 'accept');

// User rejects a recommendation
await manager.provideFeedback('user123', 'user789', 'reject');

// Get feedback history
const history = await manager.getFeedbackHistory('user123');

Python Example

import requests

class RecommendationManager:
def __init__(self, access_token):
self.access_token = access_token
self.base_url = 'https://api.playsync.com'
self.headers = {
'Authorization': f'Bearer {access_token}',
'Content-Type': 'application/json'
}

def get_recommendations(self, user_id, count=10):
response = requests.get(
f'{self.base_url}/v1/users/{user_id}/recommendations',
params={'count': count},
headers=self.headers
)
return response.json()

def provide_feedback(self, user_id, candidate_id, response):
data = {
'candidate_id': candidate_id,
'response': response
}
response = requests.post(
f'{self.base_url}/v1/users/{user_id}/recommendations/feedback',
json=data,
headers=self.headers
)
return response.json()

def get_feedback_history(self, user_id):
response = requests.get(
f'{self.base_url}/v1/users/{user_id}/recommendations/feedback',
headers=self.headers
)
return response.json()

# Usage
manager = RecommendationManager('your-access-token')

# Get recommendations
recommendations = manager.get_recommendations('user123', 5)

# Provide feedback
manager.provide_feedback('user123', 'user456', 'accept')
manager.provide_feedback('user123', 'user789', 'reject')

# Get history
history = manager.get_feedback_history('user123')

Future Enhancements

The recommendation feedback system is designed to be extensible. Future enhancements may include:

  • Time-based re-recommendation: Show rejected candidates again after a configurable time period
  • Profile change detection: Re-recommend when user or candidate profiles change significantly
  • Feedback reasons: Track why users reject recommendations
  • Confidence levels: Allow users to indicate how certain they are about their decision
  • Analytics dashboard: Provide insights into recommendation effectiveness

Current Behavior Notes

  • Permanent exclusion: Currently, both accept and reject responses permanently exclude candidates
  • No time limits: Rejected recommendations are not automatically re-shown after any time period
  • No profile change detection: The system doesn't automatically re-recommend when profiles change
  • Simple feedback model: Only supports accept/reject responses (no reasons or confidence levels)

This design prioritizes user experience by preventing repetitive recommendations while maintaining a simple, reliable feedback system.