> ## Documentation Index
> Fetch the complete documentation index at: https://docs.rated.network/llms.txt
> Use this file to discover all available pages before exploring further.

# Private Sets

export const Endpoint = ({type, path, url}) => {
  const methodColors = {
    post: 'bg-blue-400/20 text-blue-700 dark:bg-blue-400/20 dark:text-blue-400',
    get: 'bg-green-400/20 text-green-700 dark:bg-green-400/20 dark:text-green-400',
    put: 'bg-yellow-400/20 text-yellow-700 dark:bg-yellow-400/20 dark:text-yellow-400',
    delete: 'bg-red-400/20 text-red-700 dark:bg-red-400/20 dark:text-red-400',
    patch: 'bg-orange-400/20 text-orange-700 dark:bg-orange-400/20 dark:text-orange-400'
  };
  const pathParts = path.startsWith('/') ? path.substring(1).split('/') : path.split('/');
  return <a href={url} className="relative flex-1 flex gap-2 min-w-0 rounded-xl items-center cursor-pointer p-1.5 border-standard">
        <div className={`rounded-lg font-bold px-1.5 py-0.5 text-sm leading-5 ${methodColors[type.toLowerCase()]}`}>
          {type}
        </div>
        <div className="flex items-center space-x-2 overflow-x-auto flex-1 no-scrollbar">
          <div className="group flex items-center flex-1 gap-0.5 font-mono">
            {url && <div className="absolute right-0 p-2 rounded-lg hidden group-hover:block">
                <Icon icon="arrow-right" />
              </div>}
            {pathParts.map((part, i) => {
    const isParam = part.includes('{');
    return <>
                  <div className="text-sm text-gray-400">/</div>
                  {isParam ? <div className="text-sm font-mono font-medium rounded-md px-1 border-2 min-w-max text-[#2AB673] bg-[#2AB673]/10 border-[#2AB673]/30">
                      {part}
                    </div> : <div className="text-sm font-medium text-gray-800 dark:text-white min-w-max">
                      {part}
                    </div>}
                </>;
  })}
          </div>
        </div>
      </a>;
};

Private sets is a self-serve feature designed to enable organizations to curate a set of validators, each marked with a unique tag. This tag, carrying an identifier specific to your organization, ensures that only you can view the performance and rewards metrics for it. Displayed within your console, these tags streamline analysis processes and let you perform A/B testing on your node setup or group together validators for a specific customer confidentially.

### Getting Started

Build and Growth API users can create private sets. Build tier comes with max 4 sets while Growth comes with 20.

### Step 1: Creating a Tag and associating validators to it

To call a set's effectiveness, you must first create a tag which acts as a unique identifier for the set.

<Endpoint path="/v1/tags" type="POST" url="/rated-api/api-reference/v1/ethereum/private-sets/create-a-new-tag" />

**Body parameters (Required)**

| Name   | Type   | Description      |
| :----- | :----- | :--------------- |
| `name` | string | Name for the tag |

**Response**

<CodeGroup>
  ```json 200 theme={null}
  {
    "id": "string",
    "name": "string",
    "network": "mainnet",
    "organizationId": "string",
    "createdBy": "string",
    "createdAt": "2024-03-14T18:12:14.677Z",
    "updatedAt": "2024-03-14T18:12:14.677Z"
  }
  ```
</CodeGroup>

Using the `id` that you get in the response above, call the following endpoint to associate validators with the tag

<Endpoint path="/v1/tags/{id}/validators" type="POST" url="/rated-api/api-reference/v1/ethereum/private-sets/add-validators-to-a-tag" />

**Body parameters (Required)**

| Name      | Type  | Description                                 |
| :-------- | :---- | :------------------------------------------ |
| `pubkeys` | array | list of keys you wish to associate to a tag |

**Response**

<CodeGroup>
  ```json 200 theme={null}
  {
      "tag": "string",
      "pubkeysAdded": integer
  }
  ```
</CodeGroup>

Once you have a tag with validator mappings, you can move to Step 2.

<Check>
  To add more validators to a tag, call `POST` `/v1/tags/{id}/validators` with the new keys you'd like to add. Similarly, to remove a pubkey from an existing tag, call`DELETE` `/v1/tags/{id}/validators/{pubkey}.`
</Check>

<Warning>
  Removing keys from a tag doesn't erase their impact on historical performance ie performance of a removed pubkey continues to impact the all-time performance of a set.
</Warning>

### Step 2: Calling the performance and rewards endpoints for your set

Using the tag's ID, call the sets endpoints to retrieve performance and rewards metrics. These endpoints operate similar to the /operators/ endpoints with similar granularities and refresh windows.

<Endpoint path="/v1/eth/sets/{set_id}/effectiveness" type="GET" />

<br />

<Endpoint path="/v1/eth/sets/{set_id}/attestations" type="GET" />

<br />

<Endpoint path="/v1/eth/sets/{set_id}/proposals" type="GET" />

<br />

<Endpoint path="/v1/eth/sets/{set_id}/rewards" type="GET" />

<br />

<Endpoint path="/v1/eth/sets/{set_id}/penalties" type="GET" />

**Query parameters**

| Name          | Type    | Value                                                                                       |
| :------------ | :------ | :------------------------------------------------------------------------------------------ |
| `granularity` | enum    | `hour`or `day`                                                                              |
| `fromDate`    | date    | the date from which you wish to retrieve the data                                           |
| `toDate`      | date    | the date upto which you wish to retrieve the data                                           |
| `limit`       | integer | the number of rows returned per page                                                        |
| `offset`      | integer | offset allows you to omit a specified number of rows before the beginning of the result set |

**Response**

<CodeGroup>
  ```json 200 (effectiveness) theme={null}
  {
  "pages": 3,
  "results": [
      {
        "hour": null,
        "day": 796,
        "date": 2023-01-01,
        "startEpoch": 179324,
        "endEpoch": 179100,
        "validatorCount": 16075,
        "avgInclusionDelay": 1.0138705386457403,
        "avgUptime": 0.9999466390184881,
        "avgCorrectness": 0.9929917401071404,
        "avgProposerEffectiveness": 99.53271028037379,
        "avgValidatorEffectiveness": 97.96642775943795,
        "avgAttesterEffectiveness": 97.9580945527236
      }
    ],
    "previous": "string",
    "next": "string"
  }
  ```

  ```json 200 (attestations) theme={null}
  {
  "pages": 3,
  "results": [
      {
        "hour": null,
        "day": 796,
        "date": 2023-01-01,
        "startEpoch": 179324,
        "endEpoch": 179100,
        "validatorCount": 16075,
        "totalUniqueAttestations": 3616682,
        "sumMissedAttestations": 193,
        "sumMissedSyncSignatures": 2837,
        "sumCorrectHead": 3547355,
        "sumCorrectTarget": 3612248,
        "sumCorrectSource": 3614403,
        "sumWrongHeadVotes": 48767,
        "sumWrongTargetVotes": 4434,
        "sumWrongSourcetVotes": 4434,
        "sumLateSourceVotes": 2279,
        "sumLateTargetVotes": 0,
        "sumLateHeadVotes": 0,
        "avgAttesterEffectiveness": 97.9580945527236
      }
    ],
    "previous": "string",
    "next": "string"
  }
  ```

  ```json 200 (proposals) theme={null}
  {
  "pages": 3,
  "results": [
      {
        "hour": null,
        "day": 796,
        "date": 2023-01-01,
        "startEpoch": 179324,
        "endEpoch": 179100,
        "validatorCount": 16075,
        "sumProposedCount": 213,
        "sumProposerDutiesCount": 214,
        "avgProposerEffectiveness": 99.53271028037379
      }
    ],
    "previous": "string",
    "next": "string"
  }
  ```

  ```json 200 (rewards) theme={null}
  {
  "pages": 3,
  "results": [
      {
        "hour": null,
        "day": 796,
        "date": 2023-01-01,
        "startEpoch": 179324,
        "endEpoch": 179100,
        "validatorCount": 16075,
        "sumEarnings": 56766373292,
        "sumEstimatedRewards": 56675239144,
        "sumPriorityFees": 10662221791,
        "sumBaselineMev": 5266131924,
        "sumMissedExecutionRewards": 58181568,
        "sumConsensusBlockRewards": 6554423259,
        "sumMissedConsensusBlockRewards": 31228533,
        "sumAllRewards": 72694727007,
        "sumAttestationRewards": 50120815885,
        "sumMissedAttestationRewards": 269961427,
        "sumMissedSyncCommitteeRewards": 44317643,
        "sumExternallySourcedExecutionRewards": 14862131536
      }
    ],
    "previous": "string",
    "next": "string"
  }
  ```

  ```json 200 (penalties) theme={null}
  {
  "pages": 3,
  "results": [
      {
        "hour": null,
        "day": 796,
        "date": 2023-01-01,
        "startEpoch": 179324,
        "endEpoch": 179100,
        "validatorCount": 16075,
        "sumEstimatedPenalties": -82967688,
        "sumSyncCommitteePenalties": -44317643,
        "sumWrongTargetPenalties": -28763358,
        "sumLateTargetPenalties": 0,
        "sumMissedAttestationPenalties": -1926140,
        "sumWrongHeadPenalties": 0,
        "sumLateSourcePenalties": -7960547
      }
    ],
    "previous": "string",
    "next": "string"
  }
  ```
</CodeGroup>
