Skip to main content

Overview

The rating system in IOTA Repstation allows parties to rate each other after completing a deal. Ratings are permanent, blockchain-recorded assessments that build into reputation profiles over time.

Rating Requirements

Deal-Bound Ratings

All ratings must be tied to a specific deal:
  • Deal must be in CLOSED state
  • Only deal participants can rate each other
  • Each participant can rate the other party once per deal
  • Ratings reference the specific deal and subject

Score Range

Ratings use a standardized 1-100 score system:
  • 1-20: Very Poor
  • 21-40: Poor
  • 41-60: Average
  • 61-80: Good
  • 81-100: Excellent

Rating Categories

Categories help organize different aspects of performance:

Common Categories

  • reliability - Did they deliver as promised?
  • communication - How well did they communicate?
  • quality - Was the work/product high quality?
  • speed - How quickly did they complete the work?
  • professionalism - Were they professional throughout?

Custom Categories

Applications can define their own categories:
// NFT Marketplace
const categories = [
  'artwork_quality',
  'authenticity',
  'shipping_speed',
  'packaging'
];

// Service Platform  
const categories = [
  'technical_skill',
  'deadline_adherence', 
  'code_quality',
  'project_management'
];

Creating Ratings

Basic Rating

const { endorsement_id } = await client.rate({
  signer: raterWallet,
  deal_id: completedDealId,
  score: 85,
  category: 'reliability'
});

Multiple Category Ratings

Rate different aspects separately:
// Rate communication
await client.rate({
  signer: buyerWallet,
  deal_id: dealId,
  score: 92,
  category: 'communication'
});

// Rate delivery speed
await client.rate({
  signer: buyerWallet,
  deal_id: dealId,
  score: 78,
  category: 'speed'
});

// Rate product quality
await client.rate({
  signer: buyerWallet,
  deal_id: dealId,
  score: 95,
  category: 'quality'
});

Rating Management

Updating Ratings

Ratings can be updated using the endorsement capability:
await client.updateRating({
  signer: raterWallet,
  endorsement_id: endorsementId,
  endorsement_cap_id: endorsementCapId,
  new_score: 90, // Updated score
});

Revoking Ratings

Ratings can be completely revoked:
await client.revokeRating({
  signer: raterWallet,
  endorsement_id: endorsementId,
  endorsement_cap_id: endorsementCapId
});
Revoked ratings are permanently removed and cannot be restored. Use updates instead of revocation when possible.

Rating Aggregation

Global Reputation

All ratings for a user are aggregated globally:
const profile = await client.getReputationProfile({
  walletAddress: userWallet
});

console.log(`Global average: ${profile.global.average}/100`);
console.log(`Total ratings: ${profile.global.count}`);

App-Scoped Reputation

Ratings are also tracked per application:
// Each app namespace maintains separate stats
profile.appScoped.forEach(app => {
  console.log(`App: ${app.appOwner}`);
  console.log(`Average: ${app.stats.average}/100`);
  console.log(`Count: ${app.stats.count}`);
});

Rating Data Structure

Endorsement Object

interface Endorsement {
  id: string;
  rater: string;           // Wallet address of rater
  deal_id: string;         // Associated deal
  score: number;           // 1-100 rating score
  category: string;        // Rating category
  timestamp: string;       // When rating was created
  last_updated?: string;   // When rating was last modified
}

Rating Statistics

interface RatingStats {
  average: number;         // Average of all ratings
  count: number;          // Total number of ratings
  distribution?: {        // Optional score distribution
    excellent: number;    // 81-100 scores
    good: number;        // 61-80 scores  
    average: number;     // 41-60 scores
    poor: number;        // 21-40 scores
    very_poor: number;   // 1-20 scores
  };
}

Best Practices

1. Meaningful Categories

Use categories that matter to your use case:
// Good for marketplaces
const marketplaceCategories = [
  'product_quality',
  'shipping_speed', 
  'customer_service',
  'value_for_money'
];

// Good for freelancing
const freelanceCategories = [
  'skill_level',
  'communication',
  'deadline_compliance',
  'work_quality'
];

2. Encourage Honest Ratings

Design your UI to promote fair ratings:
function RatingComponent({ onSubmit }) {
  const [scores, setScores] = useState({});
  
  return (
    <div className="rating-form">
      <h3>Rate Your Experience</h3>
      
      <RatingSlider
        label="Communication (How well did they communicate?)"
        value={scores.communication || 50}
        onChange={(score) => setScores({...scores, communication: score})}
        helpText="Consider responsiveness, clarity, and professionalism"
      />
      
      <RatingSlider
        label="Quality (How was the work quality?)"  
        value={scores.quality || 50}
        onChange={(score) => setScores({...scores, quality: score})}
        helpText="Consider attention to detail and meeting requirements"
      />
      
      <button onClick={() => submitRatings(scores)}>
        Submit Ratings
      </button>
    </div>
  );
}

3. Rating Timing

Prompt for ratings at the right time:
class OrderService {
  async markOrderDelivered(orderId: string) {
    const order = await this.getOrder(orderId);
    
    // Close the deal first
    await this.reputation.closeDeal({
      signer: this.adminWallet,
      deal_id: order.reputationDealId
    });
    
    // Send rating reminders after short delay
    setTimeout(() => {
      this.sendRatingReminder(order.buyerId, order.id);
      this.sendRatingReminder(order.sellerId, order.id);
    }, 24 * 60 * 60 * 1000); // 24 hours
  }
}

Error Handling

Common rating errors:
try {
  await client.rate({
    signer: wallet,
    deal_id: dealId,
    score: score,
    category: category
  });
} catch (error) {
  switch (error.code) {
    case 'DEAL_NOT_CLOSED':
      showError('Deal must be completed before rating');
      break;
    case 'ALREADY_RATED':
      showError('You have already rated this deal. Use update instead.');
      break;
    case 'NOT_DEAL_PARTICIPANT':
      showError('Only deal participants can rate each other');
      break;
    case 'INVALID_SCORE':
      showError('Rating must be between 1 and 100');
      break;
    case 'CANNOT_RATE_SELF':
      showError('You cannot rate yourself');
      break;
  }
}

Integration Examples

E-commerce Rating Flow

class EcommerceRatings {
  async handleOrderCompletion(orderId: string) {
    const order = await this.db.orders.findById(orderId);
    
    // Close reputation deal
    await this.reputation.closeDeal({
      signer: this.adminWallet,
      deal_id: order.reputationDealId
    });
    
    // Enable rating UI for both parties
    await this.enableRatings(order.buyerId, order.sellerId, order.id);
  }
  
  async submitBuyerRating(buyerId: string, orderId: string, ratings: any) {
    const order = await this.db.orders.findById(orderId);
    
    // Rate seller on multiple categories
    for (const [category, score] of Object.entries(ratings)) {
      await this.reputation.rate({
        signer: buyerId,
        deal_id: order.reputationDealId,
        score: score as number,
        category
      });
    }
  }
}

Service Platform Ratings

class ServiceRatings {
  async completeProject(projectId: string, clientId: string, providerId: string) {
    const project = await this.getProject(projectId);
    
    // Close deal
    await this.reputation.closeDeal({
      signer: clientId,
      deal_id: project.dealId
    });
    
    // Client rates provider
    await this.reputation.rate({
      signer: clientId,
      deal_id: project.dealId,
      score: project.clientRating.skill,
      category: 'technical_skill'
    });
    
    // Provider rates client
    await this.reputation.rate({
      signer: providerId,
      deal_id: project.dealId,
      score: project.providerRating.clarity,
      category: 'requirements_clarity'
    });
  }
}

Next Steps

Reputation Profiles

Learn how ratings build into comprehensive reputation profiles.

Rating API

Explore the complete rating management API.

Deal Management

Understand the deal lifecycle that enables ratings.

Integration Guide

Build rating interfaces for your application.