SureshakeDocs
API ReferenceEndpoints

Watchlist Endpoints

Create personal company watchlists and manage their membership.

Watchlists let you track companies you care about. Each watchlist is a named, per-user list of companies — watchlists are private to your account and are never visible to other users or to the companies you track.

Watchlists in the product

  • Star button. Every public company page (www.sureshake.com/c/{slug}) shows a star button. Starring a company adds it to a watchlist; starring again removes it.
  • Watchlists page. The /watchlists page lists all of your watchlists and the companies in each, with ticker and exchange context.
  • Dashboard navigation. Signed-in users have a Watchlists link in the dashboard navigation.

Everything the product does is available through the API below.

Authentication

All watchlist endpoints require an Authorization: Bearer $TOKEN header. Requests without a valid token return 401:

401 Unauthorized
{
"error": {
  "code": "UNAUTHORIZED",
  "message": "Missing or invalid Authorization header"
}
}

The examples below use Bentley Systems (entityId: 5210b6a3-5677-4bd9-8f8d-6e9dab011a28). Resolve a company's entityId from its ticker with GET /v2/entities/public/by-ticker/:ticker or from its public profile (entity.id).

List Watchlists

Retrieve all of your watchlists, newest first.

GET/v2/watchlists
curl -H "Authorization: Bearer $TOKEN" \
"https://api.sureshake.com/v2/watchlists?entityId=5210b6a3-5677-4bd9-8f8d-6e9dab011a28"
const response = await fetch(
'https://api.sureshake.com/v2/watchlists?entityId=5210b6a3-5677-4bd9-8f8d-6e9dab011a28',
{ headers: { 'Authorization': `Bearer ${token}` } },
);
const { data } = await response.json();

Query parameters

ParameterTypeDescription
entityIdstring (uuid)Optional. When provided, each watchlist row includes containsEntity — whether that company is already in the list. This is how the star button knows its state.

Response fields (data[])

FieldTypeDescription
idstring (uuid)Watchlist identifier.
namestringWatchlist name.
descriptionstring | nullOptional description.
isActivebooleanWhether the watchlist is active.
entityCountintegerNumber of companies in the watchlist.
containsEntitybooleanPresent only when ?entityId= was supplied.
createdAtstring (datetime)When the watchlist was created.
updatedAtstring (datetime)When the watchlist last changed.
200 OK
{
"data": [
  {
    "id": "b7c1f2a4-3d5e-4f60-8a9b-1c2d3e4f5a01",
    "name": "Infrastructure Software",
    "description": "Public infra-software companies I follow",
    "isActive": true,
    "entityCount": 3,
    "containsEntity": true,
    "createdAt": "2026-07-20T15:04:05.000Z",
    "updatedAt": "2026-07-23T09:12:44.000Z"
  }
],
"meta": { "total": 1, "limit": 20, "offset": 0, "hasMore": false }
}

Create a Watchlist

Create a new, empty watchlist.

POST/v2/watchlists
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Infrastructure Software", "description": "Public infra-software companies I follow"}' \
"https://api.sureshake.com/v2/watchlists"
const response = await fetch('https://api.sureshake.com/v2/watchlists', {
method: 'POST',
headers: {
  'Authorization': `Bearer ${token}`,
  'Content-Type': 'application/json',
},
body: JSON.stringify({
  name: 'Infrastructure Software',
  description: 'Public infra-software companies I follow',
}),
});
const { data } = await response.json();

Request body

FieldTypeRequiredDescription
namestringYes1–120 characters after trimming whitespace.
descriptionstringNoUp to 500 characters.
201 Created
{
"data": {
  "id": "b7c1f2a4-3d5e-4f60-8a9b-1c2d3e4f5a01",
  "name": "Infrastructure Software",
  "description": "Public infra-software companies I follow",
  "isActive": true,
  "entityCount": 0,
  "createdAt": "2026-07-23T09:00:00.000Z",
  "updatedAt": "2026-07-23T09:00:00.000Z"
},
"meta": { "timestamp": "2026-07-23T09:00:00.000Z" }
}
400 Bad RequestBlank or missing name
{
"error": {
  "code": "FST_ERR_VALIDATION",
  "message": "body/name String must contain at least 1 character(s)",
  "traceId": "2YUDzTvsxcEJxjCfGFhG4"
}
}

Get Watchlist Detail

Retrieve one watchlist with its full company list.

GET/v2/watchlists/:watchlistId
curl -H "Authorization: Bearer $TOKEN" \
"https://api.sureshake.com/v2/watchlists/b7c1f2a4-3d5e-4f60-8a9b-1c2d3e4f5a01"
const response = await fetch(
'https://api.sureshake.com/v2/watchlists/b7c1f2a4-3d5e-4f60-8a9b-1c2d3e4f5a01',
{ headers: { 'Authorization': `Bearer ${token}` } },
);
const { data } = await response.json();

The detail payload adds an entities array. Each entry carries entityId, name, slug, logoUrl, entityType, primaryExchange, primaryTicker, sureshakeTicker, and addedAt.

200 OK
{
"data": {
  "id": "b7c1f2a4-3d5e-4f60-8a9b-1c2d3e4f5a01",
  "name": "Infrastructure Software",
  "description": "Public infra-software companies I follow",
  "isActive": true,
  "entityCount": 1,
  "createdAt": "2026-07-20T15:04:05.000Z",
  "updatedAt": "2026-07-23T09:12:44.000Z",
  "entities": [
    {
      "entityId": "5210b6a3-5677-4bd9-8f8d-6e9dab011a28",
      "name": "Bentley Systems, Incorporated",
      "slug": "bentley-systems-inc",
      "logoUrl": null,
      "entityType": "company",
      "primaryExchange": "NASDAQ",
      "primaryTicker": "BSY",
      "sureshakeTicker": null,
      "addedAt": "2026-07-23T09:12:44.000Z"
    }
  ]
},
"meta": { "timestamp": "2026-07-23T10:00:00.000Z" }
}
404 Not FoundWatchlist does not exist or belongs to another user
{
"error": {
  "code": "NOT_FOUND",
  "message": "Watchlist not found: b7c1f2a4-3d5e-4f60-8a9b-1c2d3e4f5a01",
  "traceId": "aBcDeFgHiJkLmNoPqRsTu"
}
}

Rename a Watchlist

Update the display name of a watchlist owned by the current user.

PATCH/v2/watchlists/:watchlistId
curl -X PATCH \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Priority companies"}' \
"https://api.sureshake.com/v2/watchlists/b7c1f2a4-3d5e-4f60-8a9b-1c2d3e4f5a01"

The response uses the same summary shape returned when creating a watchlist. Blank names are rejected, and watchlists owned by another user return 404.

Delete a Watchlist

Delete a watchlist and its membership rows. This cannot be undone.

DELETE/v2/watchlists/:watchlistId
curl -X DELETE \
-H "Authorization: Bearer $TOKEN" \
"https://api.sureshake.com/v2/watchlists/b7c1f2a4-3d5e-4f60-8a9b-1c2d3e4f5a01"
200 OK
{
"data": {
  "watchlistId": "b7c1f2a4-3d5e-4f60-8a9b-1c2d3e4f5a01",
  "deleted": true
},
"meta": { "timestamp": "2026-07-23T10:05:00.000Z" }
}

Add a Company to a Watchlist

Add a company by its entityId. This is what the star button calls.

POST/v2/watchlists/:watchlistId/entities
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"entityId": "5210b6a3-5677-4bd9-8f8d-6e9dab011a28"}' \
"https://api.sureshake.com/v2/watchlists/b7c1f2a4-3d5e-4f60-8a9b-1c2d3e4f5a01/entities"
const response = await fetch(
'https://api.sureshake.com/v2/watchlists/b7c1f2a4-3d5e-4f60-8a9b-1c2d3e4f5a01/entities',
{
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ entityId: '5210b6a3-5677-4bd9-8f8d-6e9dab011a28' }),
},
);
200 OK
{
"data": {
  "watchlistId": "b7c1f2a4-3d5e-4f60-8a9b-1c2d3e4f5a01",
  "entityId": "5210b6a3-5677-4bd9-8f8d-6e9dab011a28",
  "added": true
},
"meta": { "timestamp": "2026-07-23T09:12:44.000Z" }
}
404 Not FoundThe entityId does not match a known company
{
"error": {
  "code": "NOT_FOUND",
  "message": "Entity not found: 019807aa-0000-4000-8000-000000000000",
  "traceId": "vWxYzAbCdEfGhIjKlMnOp"
}
}

Remove a Company from a Watchlist

DELETE/v2/watchlists/:watchlistId/entities/:entityId
curl -X DELETE \
-H "Authorization: Bearer $TOKEN" \
"https://api.sureshake.com/v2/watchlists/b7c1f2a4-3d5e-4f60-8a9b-1c2d3e4f5a01/entities/5210b6a3-5677-4bd9-8f8d-6e9dab011a28"
200 OK
{
"data": {
  "watchlistId": "b7c1f2a4-3d5e-4f60-8a9b-1c2d3e4f5a01",
  "entityId": "5210b6a3-5677-4bd9-8f8d-6e9dab011a28",
  "removed": true
},
"meta": { "timestamp": "2026-07-23T10:10:00.000Z" }
}

Error reference

StatusWhen
400Validation failure — blank watchlist name, malformed UUID, oversized fields.
401Missing or invalid bearer token.
404Watchlist not found (or owned by another user), or unknown entityId.

Watchlists are strictly per-user: another user's watchlist IDs return 404, never 403, so IDs do not leak existence.

On this page