Spaces:
Running
Service Professional Ratings API - Quick Reference
Base URL
/api/v1/ratings
Authentication
Most endpoints require JWT Bearer token:
Authorization: Bearer <your_jwt_token>
Endpoints Summary
| Method | Endpoint | Auth | Description |
|---|---|---|---|
| POST | / |
β | Create rating |
| GET | /{rating_id} |
β | Get rating by ID |
| PUT | /{rating_id} |
β | Update rating |
| DELETE | /{rating_id} |
β | Delete rating |
| POST | /list |
β | List ratings with filters |
| GET | /stats/{professional_id} |
β | Get rating statistics |
| POST | /{rating_id}/responses |
β | Add response to rating |
| POST | /{rating_id}/helpful |
β | Mark rating as helpful |
1. Create Rating
POST /api/v1/ratings/
Create a new rating for a service professional after order completion.
Request
{
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"service_professional_id": "prof_123",
"service_id": "svc_456",
"rating_score": 4.5,
"review_title": "Excellent service!",
"review_text": "Very professional and skilled. Highly recommend!",
"is_anonymous": false
}
Response (201)
{
"rating_id": "660e8400-e29b-41d4-a716-446655440001",
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"service_professional_id": "prof_123",
"customer_id": "cust_456",
"merchant_id": "merchant_789",
"service_id": "svc_456",
"rating_score": 4.5,
"review_title": "Excellent service!",
"review_text": "Very professional and skilled. Highly recommend!",
"is_verified_purchase": true,
"is_anonymous": false,
"helpful_count": 0,
"status": "active",
"created_at": "2024-02-27T10:30:00",
"updated_at": "2024-02-27T10:30:00",
"responses": []
}
Notes
- Rating score must be 1.0-5.0 in 0.5 increments (1.0, 1.5, 2.0, etc.)
- Customer ID extracted from JWT token
- Prevents duplicate ratings for same order/professional
- Order must exist and be completed
2. Get Rating by ID
GET /api/v1/ratings/{rating_id}
Retrieve a specific rating with all responses.
Response (200)
{
"rating_id": "660e8400-e29b-41d4-a716-446655440001",
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"service_professional_id": "prof_123",
"customer_id": "cust_456",
"rating_score": 4.5,
"review_title": "Excellent service!",
"review_text": "Very professional and skilled.",
"is_verified_purchase": true,
"is_anonymous": false,
"helpful_count": 5,
"status": "active",
"created_at": "2024-02-27T10:30:00",
"updated_at": "2024-02-27T10:30:00",
"responses": [
{
"response_id": "770e8400-e29b-41d4-a716-446655440002",
"rating_id": "660e8400-e29b-41d4-a716-446655440001",
"responder_id": "prof_123",
"responder_type": "professional",
"response_text": "Thank you for your feedback!",
"created_at": "2024-02-27T11:00:00",
"updated_at": "2024-02-27T11:00:00"
}
]
}
3. Update Rating
PUT /api/v1/ratings/{rating_id}
Update an existing rating (only by customer who created it).
Request
{
"rating_score": 5.0,
"review_text": "Updated review - even better than I thought!",
"review_title": "Outstanding!"
}
Response (200)
Same as Get Rating response with updated fields.
Notes
- Only the customer who created the rating can update it
- All fields are optional
- Cannot change order_id or service_professional_id
4. Delete Rating
DELETE /api/v1/ratings/{rating_id}
Soft delete a rating (sets status to 'deleted').
Response (204)
No content
Notes
- Only the customer who created the rating can delete it
- Soft delete - data remains in database with status='deleted'
- Deleted ratings don't appear in public lists
5. List Ratings
POST /api/v1/ratings/list
List ratings with filters and pagination.
Request
{
"service_professional_id": "prof_123",
"min_rating": 4.0,
"max_rating": 5.0,
"status": "active",
"limit": 20,
"offset": 0
}
Response (200)
{
"ratings": [
{
"rating_id": "660e8400-e29b-41d4-a716-446655440001",
"service_professional_id": "prof_123",
"rating_score": 4.5,
"review_title": "Excellent service!",
"review_text": "Very professional and skilled.",
"helpful_count": 5,
"status": "active",
"created_at": "2024-02-27T10:30:00",
"responses": []
}
],
"pagination": {
"limit": 20,
"offset": 0,
"total": 150
}
}
Filter Options
service_professional_id- Filter by professionalcustomer_id- Filter by customermerchant_id- Filter by merchantservice_id- Filter by servicemin_rating- Minimum rating score (1.0-5.0)max_rating- Maximum rating score (1.0-5.0)status- Filter by status (defaults to 'active')limit- Results per page (1-100, default 20)offset- Pagination offset (default 0)
6. Get Rating Statistics
GET /api/v1/ratings/stats/{service_professional_id}
Get aggregated rating statistics for a service professional.
Response (200)
{
"service_professional_id": "prof_123",
"total_ratings": 150,
"average_rating": 4.3,
"rating_distribution": {
"5": 80,
"4": 45,
"3": 15,
"2": 7,
"1": 3
},
"verified_purchase_count": 145,
"total_reviews_with_text": 120
}
Notes
- Only includes active ratings
- Average rating rounded to 2 decimal places
- Distribution shows count per star rating (1-5)
- Useful for displaying professional profiles
7. Create Response to Rating
POST /api/v1/ratings/{rating_id}/responses
Service professional, merchant, or admin can respond to a rating.
Request
{
"response_text": "Thank you for your feedback! We're glad you enjoyed our service and look forward to serving you again."
}
Response (201)
{
"response_id": "770e8400-e29b-41d4-a716-446655440002",
"rating_id": "660e8400-e29b-41d4-a716-446655440001",
"responder_id": "prof_123",
"responder_type": "professional",
"response_text": "Thank you for your feedback!",
"created_at": "2024-02-27T11:00:00",
"updated_at": "2024-02-27T11:00:00"
}
Authorization Rules
- Professional: Can respond to their own ratings
- Merchant: Can respond to ratings in their establishment
- Admin: Can respond to any rating
Notes
- Response text must be 10-1000 characters
- Multiple responses allowed per rating
- Responder type determined from JWT role
8. Mark Rating as Helpful
POST /api/v1/ratings/{rating_id}/helpful
Increment the helpful count for a rating.
Response (200)
Returns the updated rating with incremented helpful_count.
Notes
- No authentication required
- Can be called multiple times (no duplicate prevention)
- Consider implementing client-side tracking to prevent abuse
Error Responses
400 Bad Request
{
"detail": "Rating already exists for this order and professional"
}
401 Unauthorized
{
"detail": "Not authenticated"
}
403 Forbidden
{
"detail": "Not authorized to update this rating"
}
404 Not Found
{
"detail": "Rating not found"
}
500 Internal Server Error
{
"detail": "Failed to create rating: <error message>"
}
Common Use Cases
Display Professional Profile with Ratings
- GET
/api/v1/ratings/stats/{professional_id}- Get overall stats - POST
/api/v1/ratings/listwith filters - Get recent reviews
Customer Leaves Review After Service
- POST
/api/v1/ratings/- Create rating - Customer receives confirmation
Professional Responds to Review
- GET
/api/v1/ratings/{rating_id}- View rating - POST
/api/v1/ratings/{rating_id}/responses- Add response
Browse All Reviews for a Professional
- POST
/api/v1/ratings/listwithservice_professional_idfilter - Paginate through results
Rate Limiting Recommendations
Consider implementing rate limits:
- Rating creation: 5 per hour per customer
- Helpful marking: 20 per hour per IP
- Response creation: 10 per hour per professional
- List queries: 100 per minute per IP
Testing with cURL
Create Rating
curl -X POST "http://localhost:8000/api/v1/ratings/" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"order_id": "550e8400-e29b-41d4-a716-446655440000",
"service_professional_id": "prof_123",
"rating_score": 4.5,
"review_title": "Great service!",
"review_text": "Highly recommend!"
}'
Get Statistics
curl -X GET "http://localhost:8000/api/v1/ratings/stats/prof_123"
List Ratings
curl -X POST "http://localhost:8000/api/v1/ratings/list" \
-H "Content-Type: application/json" \
-d '{
"service_professional_id": "prof_123",
"limit": 10
}'
Last Updated: February 27, 2024