> For the complete documentation index, see [llms.txt](https://developers.ethos.network/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.ethos.network/api-documentation/api-v2/project-votes.md).

# Project Votes

## POST /projects/{projectId}/votes

> Cast a vote for a listings project

```json
{"openapi":"3.1.0","info":{"title":"Ethos API","version":"v2"},"tags":[{"name":"listings"},{"name":"project-votes"}],"servers":[{"url":"https://api.ethos.network/api/v2"}],"security":[{"Authorization":[]}],"components":{"securitySchemes":{"Authorization":{"type":"http","scheme":"bearer"}},"schemas":{"error.BAD_REQUEST":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Invalid input data error (400)","description":"The error information"},"error.UNAUTHORIZED":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Authorization not provided error (401)","description":"The error information"},"error.FORBIDDEN":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Insufficient access error (403)","description":"The error information"},"error.INTERNAL_SERVER_ERROR":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Internal server error error (500)","description":"The error information"}}},"paths":{"/projects/{projectId}/votes":{"post":{"operationId":"projectVotes-castVote","summary":"Cast a vote for a listings project","tags":["project-votes","listings"],"parameters":[{"in":"path","name":"projectId","schema":{"type":"integer","exclusiveMinimum":0,"maximum":2147483647},"required":true}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"voteType":{"type":"string","enum":["BULLISH","BEARISH"]},"voteReason":{"type":"string","minLength":1,"maxLength":50}},"required":["voteType"]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string","minLength":1},"newBalance":{"type":"object","properties":{"bullishVotesCast":{"type":"number","minimum":0},"bearishVotesCast":{"type":"number","minimum":0},"allocationResetDate":{"type":"string"},"canVote":{"type":"boolean"}},"required":["bullishVotesCast","bearishVotesCast","allocationResetDate","canVote"],"additionalProperties":false},"userVote":{"anyOf":[{"type":"object","properties":{"voteType":{"type":"string","enum":["BULLISH","BEARISH"]}},"required":["voteType"],"additionalProperties":false},{"type":"null"}]}},"required":["success","message","newBalance","userVote"],"additionalProperties":false}}}},"400":{"description":"Invalid input data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.BAD_REQUEST"}}}},"401":{"description":"Authorization not provided","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.UNAUTHORIZED"}}}},"403":{"description":"Insufficient access","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.FORBIDDEN"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.INTERNAL_SERVER_ERROR"}}}}}}}}}
```

## GET /projects/votes/balance

> Get the current user's vote balance, optionally for a specific listings project and season

```json
{"openapi":"3.1.0","info":{"title":"Ethos API","version":"v2"},"tags":[{"name":"listings"},{"name":"project-votes"}],"servers":[{"url":"https://api.ethos.network/api/v2"}],"security":[{"Authorization":[]}],"components":{"securitySchemes":{"Authorization":{"type":"http","scheme":"bearer"}},"schemas":{"error.BAD_REQUEST":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Invalid input data error (400)","description":"The error information"},"error.UNAUTHORIZED":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Authorization not provided error (401)","description":"The error information"},"error.FORBIDDEN":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Insufficient access error (403)","description":"The error information"},"error.NOT_FOUND":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Not found error (404)","description":"The error information"},"error.INTERNAL_SERVER_ERROR":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Internal server error error (500)","description":"The error information"}}},"paths":{"/projects/votes/balance":{"get":{"operationId":"projectVotes-getUserVoteBalance","summary":"Get the current user's vote balance, optionally for a specific listings project and season","tags":["project-votes","listings"],"parameters":[{"in":"query","name":"projectId","schema":{"type":"integer","exclusiveMinimum":0,"maximum":2147483647}},{"in":"query","name":"year","schema":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},{"in":"query","name":"period","schema":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"balance":{"type":"object","properties":{"bullishVotesCast":{"type":"number","minimum":0},"bearishVotesCast":{"type":"number","minimum":0},"allocationResetDate":{"type":"string"},"canVote":{"type":"boolean"}},"required":["bullishVotesCast","bearishVotesCast","allocationResetDate","canVote"],"additionalProperties":false},"userVote":{"anyOf":[{"type":"object","properties":{"voteType":{"type":"string","enum":["BULLISH","BEARISH"]}},"required":["voteType"],"additionalProperties":false},{"type":"null"}]}},"required":["balance"],"additionalProperties":false}}}},"400":{"description":"Invalid input data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.BAD_REQUEST"}}}},"401":{"description":"Authorization not provided","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.UNAUTHORIZED"}}}},"403":{"description":"Insufficient access","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.FORBIDDEN"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.NOT_FOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.INTERNAL_SERVER_ERROR"}}}}}}}}}
```

## Get paginated list of project voters with their vote statistics and totals

> \*\*Time Scope Options (scope parameter):\*\*\
> \- \`scope=global\`: All-time data from first vote to present\
> \- \`scope=global-dates\`: Custom date range (requires startDate & endDate)\
> \- \`scope=current-period\`: Current voting period (default - backend determines automatically)\
> \- \`scope=period\`: Specific voting period (requires year & period)\
> \
> \*\*Parameter Requirements by Scope:\*\*\
> \- \`global\`: No additional parameters needed\
> \- \`global-dates\`: Requires \`startDate\` and \`endDate\` (ISO date strings)\
> \- \`current-period\`: No additional parameters needed (default)\
> \- \`period\`: Requires \`year\` (number) and \`period\` (number)\
> \
> \*\*Examples:\*\*\
> \- All-time: \`GET /projects/123/voters?scope=global\`\
> \- Date range: \`GET /projects/123/voters?scope=global-dates\&startDate=2024-01-01\&endDate=2024-12-31\`\
> \- Current period: \`GET /projects/123/voters\` (default) or \`GET /projects/123/voters?scope=current-period\`\
> \- Specific period: \`GET /projects/123/voters?scope=period\&year=2024\&period=3\`\
> \
> \*\*Notes:\*\*\
> \- End dates extending into the future are automatically capped to the current time\
> \- Global scope uses all historical data for the project

```json
{"openapi":"3.1.0","info":{"title":"Ethos API","version":"v2"},"tags":[{"name":"listings"},{"name":"project-votes"}],"servers":[{"url":"https://api.ethos.network/api/v2"}],"paths":{"/projects/{projectId}/voters":{"get":{"operationId":"projectVotes-getProjectVoters","summary":"Get paginated list of project voters with their vote statistics and totals","description":"**Time Scope Options (scope parameter):**\n- `scope=global`: All-time data from first vote to present\n- `scope=global-dates`: Custom date range (requires startDate & endDate)\n- `scope=current-period`: Current voting period (default - backend determines automatically)\n- `scope=period`: Specific voting period (requires year & period)\n\n**Parameter Requirements by Scope:**\n- `global`: No additional parameters needed\n- `global-dates`: Requires `startDate` and `endDate` (ISO date strings)\n- `current-period`: No additional parameters needed (default)\n- `period`: Requires `year` (number) and `period` (number)\n\n**Examples:**\n- All-time: `GET /projects/123/voters?scope=global`\n- Date range: `GET /projects/123/voters?scope=global-dates&startDate=2024-01-01&endDate=2024-12-31`\n- Current period: `GET /projects/123/voters` (default) or `GET /projects/123/voters?scope=current-period`\n- Specific period: `GET /projects/123/voters?scope=period&year=2024&period=3`\n\n**Notes:**\n- End dates extending into the future are automatically capped to the current time\n- Global scope uses all historical data for the project","tags":["project-votes","listings"],"parameters":[{"in":"path","name":"projectId","schema":{"type":"integer","exclusiveMinimum":0,"maximum":2147483647},"required":true},{"in":"query","name":"orderBy","schema":{"default":"score","type":"string","enum":["score","updatedAt"]}},{"in":"query","name":"orderDirection","schema":{"default":"desc","type":"string","enum":["asc","desc"]}},{"in":"query","name":"sentiment","schema":{"type":"string","enum":["bullish","bearish"]}},{"in":"query","name":"scope","schema":{"default":"current-period","type":"string","enum":["global","global-dates","current-period","period"]}},{"in":"query","name":"startDate","schema":{"type":"string"}},{"in":"query","name":"endDate","schema":{"type":"string"}},{"in":"query","name":"year","schema":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},{"in":"query","name":"period","schema":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}},{"in":"query","name":"limit","schema":{"default":50,"type":"integer","minimum":0,"maximum":100}},{"in":"query","name":"offset","schema":{"default":0,"type":"integer","minimum":0,"maximum":2147483647}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"values":{"type":"array","items":{"type":"object","properties":{"user":{"type":"object","properties":{"id":{"type":"number"},"profileId":{"anyOf":[{"type":"number"},{"type":"null"}]},"displayName":{"type":"string"},"username":{"anyOf":[{"type":"string"},{"type":"null"}]},"avatarUrl":{"type":"string","format":"uri"},"description":{"anyOf":[{"type":"string"},{"type":"null"}]},"score":{"type":"number"},"status":{"type":"string","enum":["ACTIVE","INACTIVE","MERGED"]},"userkeys":{"type":"array","items":{"type":"string"}},"xpTotal":{"type":"number"},"xpStreakDays":{"type":"number"},"xpRemovedDueToAbuse":{"type":"boolean"},"influenceFactor":{"type":"number"},"influenceFactorPercentile":{"type":"number"},"humanVerificationStatus":{"anyOf":[{"type":"string","enum":["REQUESTED","VERIFIED","REVOKED","PENDING"]},{"type":"null"}]},"validatorNftCount":{"type":"number"},"links":{"type":"object","properties":{"profile":{"type":"string","format":"uri"},"scoreBreakdown":{"type":"string","format":"uri"}},"required":["profile","scoreBreakdown"],"additionalProperties":false},"stats":{"type":"object","properties":{"holdingsWei":{"anyOf":[{"type":"integer","format":"int64"},{"type":"null"}],"description":"Total WHUF held across the user’s addresses, in wei. Null: never computed, or last recomputed while the user held no addresses — distinct from a computed balance of 0."},"review":{"type":"object","properties":{"received":{"type":"object","properties":{"negative":{"type":"number"},"neutral":{"type":"number"},"positive":{"type":"number"}},"required":["negative","neutral","positive"],"additionalProperties":false}},"required":["received"],"additionalProperties":false},"vouch":{"type":"object","properties":{"given":{"type":"object","properties":{"amountWeiTotal":{"type":"integer","format":"int64"},"count":{"type":"number"}},"required":["amountWeiTotal","count"],"additionalProperties":false},"received":{"type":"object","properties":{"amountWeiTotal":{"type":"integer","format":"int64"},"count":{"type":"number"}},"required":["amountWeiTotal","count"],"additionalProperties":false}},"required":["given","received"],"additionalProperties":false,"description":"@deprecated Native-currency lifetime totals only. Use stats.vouchTotals (per-token). Removed after 2026-10-20."},"vouchTotals":{"minItems":1,"type":"array","items":{"type":"object","properties":{"balance":{"type":"object","properties":{"given":{"type":"integer","format":"int64"},"received":{"type":"integer","format":"int64"}},"required":["given","received"],"additionalProperties":false},"count":{"type":"object","properties":{"given":{"type":"integer","minimum":0,"maximum":9007199254740991},"received":{"type":"integer","minimum":0,"maximum":9007199254740991}},"required":["given","received"],"additionalProperties":false},"token":{"type":"object","properties":{"address":{"anyOf":[{"type":"string","description":"Ethereum address (0x-prefixed, 20 bytes)"},{"type":"null"}]},"decimals":{"type":"integer","minimum":0,"maximum":9007199254740991},"id":{"type":"string","enum":["eth","whuf"],"description":"Lowercase token identifier"}},"required":["address","decimals","id"],"additionalProperties":false}},"required":["balance","count","token"],"additionalProperties":false}},"whufGuarantee":{"anyOf":[{"type":"object","properties":{"asOf":{"type":"string"},"expiresAt":{"anyOf":[{"type":"string"},{"type":"null"}]},"guaranteedWei":{"type":"integer","format":"int64"},"status":{"type":"string","enum":["active","enrolling","expired"]}},"required":["asOf","expiresAt","guaranteedWei","status"],"additionalProperties":false},{"type":"null"}],"description":"The profile’s WHUF price guarantee, summed across its wallets. Null when the profile holds no guarantee account, whether because the accounting has not reached it yet or because it was not eligible; the price-guarantee endpoint tells those apart. Enrolling coverage is provisional until the token unlocks and fixes it. asOf is when the accounting last changed this profile’s coverage or enrollment — not when it last ran."}},"required":["holdingsWei","review","vouch","vouchTotals","whufGuarantee"],"additionalProperties":false}},"required":["id","profileId","displayName","username","avatarUrl","description","score","status","userkeys","xpTotal","xpStreakDays","xpRemovedDueToAbuse","influenceFactor","influenceFactorPercentile","validatorNftCount","links","stats"],"additionalProperties":false},"bullishCount":{"type":"number","minimum":0},"bearishCount":{"type":"number","minimum":0},"totalVotes":{"type":"number","minimum":0},"firstVoteAt":{"type":"string"},"lastVoteAt":{"type":"string"},"bullishReasons":{"type":"array","items":{"type":"object","properties":{"voteReason":{"anyOf":[{"type":"string"},{"type":"null"}]},"totalVotes":{"type":"number"}},"required":["voteReason","totalVotes"],"additionalProperties":false}},"bearishReasons":{"type":"array","items":{"type":"object","properties":{"voteReason":{"anyOf":[{"type":"string"},{"type":"null"}]},"totalVotes":{"type":"number"}},"required":["voteReason","totalVotes"],"additionalProperties":false}}},"required":["user","bullishCount","bearishCount","totalVotes","firstVoteAt","lastVoteAt","bullishReasons","bearishReasons"],"additionalProperties":false}},"total":{"type":"number"},"limit":{"type":"number"},"offset":{"type":"number"},"totals":{"type":"object","properties":{"totalVoters":{"type":"number","minimum":0},"totalBullishVoters":{"type":"number","minimum":0},"totalBearishVoters":{"type":"number","minimum":0},"totalBullishVotes":{"type":"number","minimum":0},"totalBearishVotes":{"type":"number","minimum":0}},"required":["totalVoters","totalBullishVoters","totalBearishVoters","totalBullishVotes","totalBearishVotes"],"additionalProperties":false}},"required":["values","total","limit","offset","totals"],"additionalProperties":false}}}},"400":{"description":"Invalid input data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.BAD_REQUEST"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.NOT_FOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.INTERNAL_SERVER_ERROR"}}}}}}}},"components":{"schemas":{"error.BAD_REQUEST":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Invalid input data error (400)","description":"The error information"},"error.NOT_FOUND":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Not found error (404)","description":"The error information"},"error.INTERNAL_SERVER_ERROR":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Internal server error error (500)","description":"The error information"}}}}
```

## Reset the voting period for all users (Admin only)

> Advances to the next voting period, re-enabling every profile’s per-project votes

```json
{"openapi":"3.1.0","info":{"title":"Ethos API","version":"v2"},"tags":[{"name":"listings"},{"name":"project-votes"}],"servers":[{"url":"https://api.ethos.network/api/v2"}],"security":[{"Authorization":[]}],"components":{"securitySchemes":{"Authorization":{"type":"http","scheme":"bearer"}},"schemas":{"error.UNAUTHORIZED":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Authorization not provided error (401)","description":"The error information"},"error.FORBIDDEN":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Insufficient access error (403)","description":"The error information"},"error.INTERNAL_SERVER_ERROR":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Internal server error error (500)","description":"The error information"}}},"paths":{"/projects/votes/reallocate":{"post":{"operationId":"projectVotes-reallocateVotes","summary":"Reset the voting period for all users (Admin only)","description":"Advances to the next voting period, re-enabling every profile’s per-project votes","tags":["project-votes","listings"],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"allocationsCreated":{"type":"integer","minimum":0,"maximum":9007199254740991},"totalVotesAllocated":{"type":"integer","minimum":0,"maximum":9007199254740991},"usersAffected":{"type":"integer","minimum":0,"maximum":9007199254740991},"message":{"type":"string","minLength":1}},"required":["allocationsCreated","totalVotesAllocated","usersAffected","message"],"additionalProperties":false}}}},"401":{"description":"Authorization not provided","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.UNAUTHORIZED"}}}},"403":{"description":"Insufficient access","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.FORBIDDEN"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.INTERNAL_SERVER_ERROR"}}}}}}}}}
```

## Get bulk user project vote totals with flexible time range support

> \*\*Time Scope Options (scope parameter):\*\*\
> \- \`scope=global\`: All-time data from first vote to present\
> \- \`scope=global-dates\`: Custom date range (requires startDate & endDate)\
> \- \`scope=current-period\`: Current voting period (default - backend determines automatically)\
> \- \`scope=period\`: Specific voting period (requires year & period)\
> \
> \*\*Parameter Requirements by Scope:\*\*\
> \- \`global\`: No additional parameters needed\
> \- \`global-dates\`: Requires \`startDate\` and \`endDate\` (ISO date strings)\
> \- \`current-period\`: No additional parameters needed (default)\
> \- \`period\`: Requires \`year\` (number) and \`period\` (number)\
> \
> \*\*Examples:\*\*\
> \- All-time: \`GET /projects/PROJECT\_ID/bulk-totals?scope=global\`\
> \- Date range: \`GET /projects/PROJECT\_ID/bulk-totals?scope=global-dates\&startDate=2024-01-01\&endDate=2024-12-31\`\
> \- Current period: \`GET /projects/PROJECT\_ID/bulk-totals\` (default) or \`GET /projects/PROJECT\_ID/bulk-totals?scope=current-period\`\
> \- Specific period: \`GET /projects/PROJECT\_ID/bulk-totals?scope=period\&year=2024\&period=3\`\
> \
> \*\*Notes:\*\*\
> \- End dates extending into the future are automatically capped to the current time\
> \- Global scope uses all historical data for the project

```json
{"openapi":"3.1.0","info":{"title":"Ethos API","version":"v2"},"tags":[{"name":"listings"},{"name":"project-votes"}],"servers":[{"url":"https://api.ethos.network/api/v2"}],"paths":{"/projects/votes/bulk-totals":{"get":{"operationId":"projectVotes-getBulkUserProjectVoteTotals","summary":"Get bulk user project vote totals with flexible time range support","description":"**Time Scope Options (scope parameter):**\n- `scope=global`: All-time data from first vote to present\n- `scope=global-dates`: Custom date range (requires startDate & endDate)\n- `scope=current-period`: Current voting period (default - backend determines automatically)\n- `scope=period`: Specific voting period (requires year & period)\n\n**Parameter Requirements by Scope:**\n- `global`: No additional parameters needed\n- `global-dates`: Requires `startDate` and `endDate` (ISO date strings)\n- `current-period`: No additional parameters needed (default)\n- `period`: Requires `year` (number) and `period` (number)\n\n**Examples:**\n- All-time: `GET /projects/PROJECT_ID/bulk-totals?scope=global`\n- Date range: `GET /projects/PROJECT_ID/bulk-totals?scope=global-dates&startDate=2024-01-01&endDate=2024-12-31`\n- Current period: `GET /projects/PROJECT_ID/bulk-totals` (default) or `GET /projects/PROJECT_ID/bulk-totals?scope=current-period`\n- Specific period: `GET /projects/PROJECT_ID/bulk-totals?scope=period&year=2024&period=3`\n\n**Notes:**\n- End dates extending into the future are automatically capped to the current time\n- Global scope uses all historical data for the project","tags":["project-votes","listings"],"parameters":[{"in":"query","name":"projectId","schema":{"type":"integer","exclusiveMinimum":0,"maximum":2147483647},"required":true},{"in":"query","name":"profileIds","schema":{"minItems":1,"maxItems":100,"type":"array","items":{"type":"integer","exclusiveMinimum":0,"maximum":2147483647}},"required":true},{"in":"query","name":"scope","schema":{"default":"current-period","type":"string","enum":["global","global-dates","current-period","period"]}},{"in":"query","name":"startDate","schema":{"type":"string"}},{"in":"query","name":"endDate","schema":{"type":"string"}},{"in":"query","name":"year","schema":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},{"in":"query","name":"period","schema":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","propertyNames":{"type":"integer","exclusiveMinimum":0,"maximum":2147483647},"additionalProperties":{"type":"object","properties":{"totalBullishVotes":{"type":"integer","format":"int64"},"totalBearishVotes":{"type":"integer","format":"int64"},"bullishReasons":{"type":"array","items":{"type":"object","properties":{"voteReason":{"anyOf":[{"type":"string"},{"type":"null"}]},"totalVotes":{"type":"number"}},"required":["voteReason","totalVotes"],"additionalProperties":false}},"bearishReasons":{"type":"array","items":{"type":"object","properties":{"voteReason":{"anyOf":[{"type":"string"},{"type":"null"}]},"totalVotes":{"type":"number"}},"required":["voteReason","totalVotes"],"additionalProperties":false}}},"required":["totalBullishVotes","totalBearishVotes","bullishReasons","bearishReasons"],"additionalProperties":false}}}}},"400":{"description":"Invalid input data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.BAD_REQUEST"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.NOT_FOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.INTERNAL_SERVER_ERROR"}}}}}}}},"components":{"schemas":{"error.BAD_REQUEST":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Invalid input data error (400)","description":"The error information"},"error.NOT_FOUND":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Not found error (404)","description":"The error information"},"error.INTERNAL_SERVER_ERROR":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Internal server error error (500)","description":"The error information"}}}}
```

## Get project vote chart data with flexible time range and aggregation options

> \*\*Time Scope Options (scope parameter):\*\*\
> \- \`scope=global\`: All-time data from first vote to present\
> \- \`scope=global-dates\`: Custom date range (requires startDate & endDate)\
> \- \`scope=current-period\`: Current voting period (default - backend determines automatically)\
> \- \`scope=period\`: Specific voting period (requires year & period)\
> \
> \*\*Parameter Requirements by Scope:\*\*\
> \- \`global\`: No additional parameters needed\
> \- \`global-dates\`: Requires \`startDate\` and \`endDate\` (ISO date strings)\
> \- \`current-period\`: No additional parameters needed (default)\
> \- \`period\`: Requires \`year\` (number) and \`period\` (number)\
> \
> \*\*Time Aggregation (bucket parameter):\*\*\
> \- Available buckets: '1 minute', '5 minutes', '15 minutes', '30 minutes', '1 hour', '2 hours', '6 hours', '12 hours', '1 day', '1 week', '1 month'\
> \- If bucket is omitted, the API auto-selects an optimal bucket size based on the time range to prevent excessive data points\
> \- For large time spans with small buckets, an error will be returned with a suggested larger bucket\
> \- Maximum data points: 2000 (for performance)\
> \
> \*\*Examples:\*\*\
> \- All-time: \`GET /projects/123/chart?scope=global\`\
> \- Date range: \`GET /projects/123/chart?scope=global-dates\&startDate=2024-01-01\&endDate=2024-12-31\`\
> \- Current period: \`GET /projects/123/chart\` (default) or \`GET /projects/123/chart?scope=current-period\`\
> \- Specific period: \`GET /projects/123/chart?scope=period\&year=2024\&period=3\`\
> \
> \*\*Notes:\*\*\
> \- End dates extending into the future are automatically capped to the current time\
> \- Global scope uses all historical data for the project

```json
{"openapi":"3.1.0","info":{"title":"Ethos API","version":"v2"},"tags":[{"name":"listings"},{"name":"project-votes"}],"servers":[{"url":"https://api.ethos.network/api/v2"}],"paths":{"/projects/{projectId}/chart":{"get":{"operationId":"projectVotes-getProjectVoteChart","summary":"Get project vote chart data with flexible time range and aggregation options","description":"**Time Scope Options (scope parameter):**\n- `scope=global`: All-time data from first vote to present\n- `scope=global-dates`: Custom date range (requires startDate & endDate)\n- `scope=current-period`: Current voting period (default - backend determines automatically)\n- `scope=period`: Specific voting period (requires year & period)\n\n**Parameter Requirements by Scope:**\n- `global`: No additional parameters needed\n- `global-dates`: Requires `startDate` and `endDate` (ISO date strings)\n- `current-period`: No additional parameters needed (default)\n- `period`: Requires `year` (number) and `period` (number)\n\n**Time Aggregation (bucket parameter):**\n- Available buckets: '1 minute', '5 minutes', '15 minutes', '30 minutes', '1 hour', '2 hours', '6 hours', '12 hours', '1 day', '1 week', '1 month'\n- If bucket is omitted, the API auto-selects an optimal bucket size based on the time range to prevent excessive data points\n- For large time spans with small buckets, an error will be returned with a suggested larger bucket\n- Maximum data points: 2000 (for performance)\n\n**Examples:**\n- All-time: `GET /projects/123/chart?scope=global`\n- Date range: `GET /projects/123/chart?scope=global-dates&startDate=2024-01-01&endDate=2024-12-31`\n- Current period: `GET /projects/123/chart` (default) or `GET /projects/123/chart?scope=current-period`\n- Specific period: `GET /projects/123/chart?scope=period&year=2024&period=3`\n\n**Notes:**\n- End dates extending into the future are automatically capped to the current time\n- Global scope uses all historical data for the project","tags":["project-votes","listings"],"parameters":[{"in":"path","name":"projectId","schema":{"type":"integer","exclusiveMinimum":0,"maximum":2147483647},"required":true},{"in":"query","name":"bucket","schema":{"type":"string","enum":["1 minute","5 minutes","15 minutes","30 minutes","1 hour","2 hours","6 hours","12 hours","1 day","1 week","1 month"]}},{"in":"query","name":"scope","schema":{"default":"current-period","type":"string","enum":["global","global-dates","current-period","period"]}},{"in":"query","name":"startDate","schema":{"type":"string"}},{"in":"query","name":"endDate","schema":{"type":"string"}},{"in":"query","name":"year","schema":{"type":"integer","minimum":-9007199254740991,"maximum":9007199254740991}},{"in":"query","name":"period","schema":{"type":"integer","exclusiveMinimum":0,"maximum":9007199254740991}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"array","items":{"type":"object","properties":{"timeBucket":{"type":"string"},"totalBullishVotes":{"type":"integer","format":"int64"},"totalBearishVotes":{"type":"integer","format":"int64"},"bullishVotes":{"type":"integer","format":"int64"},"bearishVotes":{"type":"integer","format":"int64"},"uniqueVoters":{"type":"integer","format":"int64"}},"required":["timeBucket"],"additionalProperties":false}}}}},"400":{"description":"Invalid input data","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.BAD_REQUEST"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.NOT_FOUND"}}}},"500":{"description":"Internal server error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/error.INTERNAL_SERVER_ERROR"}}}}}}}},"components":{"schemas":{"error.BAD_REQUEST":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Invalid input data error (400)","description":"The error information"},"error.NOT_FOUND":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Not found error (404)","description":"The error information"},"error.INTERNAL_SERVER_ERROR":{"type":"object","properties":{"message":{"type":"string","description":"The error message"},"code":{"type":"string","description":"The error code"},"issues":{"description":"An array of issues that were responsible for the error","type":"array","items":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"],"additionalProperties":false}}},"required":["message","code"],"additionalProperties":false,"title":"Internal server error error (500)","description":"The error information"}}}}
```
