# Data model

What each object in the API holds, how objects connect, and the values their status fields take. For the complete list of fields on every type, browse the full schema on Apollo Studio.

URL: https://www.success.co/docs/guides/api-data-model  
Published: 2026-11-12

## Fields every object has

Every object shares these fields, so they're not repeated in the tables below:

| Field | What it holds |
| --- | --- |
| `id` | The item's ID: a UUID, used in `item(id:)` queries and in update mutations. |
| `companyId` | The company the item belongs to. Required when you create anything. |
| `stateId` | `ACTIVE`, or `DELETED` once someone deletes it. Filter on `ACTIVE` to match the app. |
| `createdAt`, `updatedAt` | When the item was created and last changed (UTC). |
| `lastUpdatedByUserId` | Who changed it last, as a user ID. Follow `lastUpdatedByUser` for their name. |

In the tables, **required** means you must send the field when you create the item.

## Users and teams

`users` are the people in your company. A person has a different user ID in each company they belong to.

| Field | What it holds |
| --- | --- |
| `firstName`, `lastName`, `email`, `jobTitle` | Who they are. |
| `userPermissionId` | Their role: `OWNER`, `ADMIN`, `MANAGER`, `TEAMMEMBER`, `OBSERVER`, `IMPLEMENTER` and others. See the `userPermissions` list. |
| `userStatusId` | `ACTIVE`, or `INACTIVE` for people who've been deactivated. |
| `timeZone`, `languageId` | Their settings, such as `Europe/Dublin` and `en`. |

`teams` are the teams in your company. `isLeadership` is `true` for the Leadership Team. A team's people are in `usersOnTeams`, a linking list with one record per person per team:

```graphql
query {
  teams(filter: { stateId: { equalTo: "ACTIVE" } }) {
    nodes {
      id
      name
      isLeadership
      usersOnTeams(filter: { stateId: { equalTo: "ACTIVE" } }) {
        nodes { user { id firstName lastName } }
      }
    }
  }
}
```

To add someone to a team, create a `usersOnTeam` with their `userId`, the `teamId` and your `companyId`. To take them off, set its `stateId` to `DELETED`.

## To-dos

`todos` are 7-day action items, each owned by one person on one team.

| Field | What it holds | Required |
| --- | --- | --- |
| `name` | The To-do itself |  |
| `desc` | Details, as HTML. Send `""` for none. | **Yes** |
| `teamId` | The team it belongs to | **Yes** |
| `userId` | Who owns it |  |
| `todoStatusId` | `TODO` (open) or `COMPLETE` (done) | **Yes** |
| `dueDate` | `YYYY-MM-DD` |  |
| `priorityNo` | Priority; send `999` for none | **Yes** |
| `type` | `team`, or `private` for a private To-do |  |
| `meetingId` | The meeting it was raised in | if any |
| `statusUpdatedAt` | When its status last changed |  |

Follow `team`, `user`, `todoStatus` and `meeting` for the related items.

## Issues

`issues` are the Issues List: things to discuss and solve (IDS™).

| Field | What it holds | Required |
| --- | --- | --- |
| `name`, `desc` | The Issue and its details (HTML) |  |
| `teamId` | The team whose list it's on | **Yes** |
| `userId` | Who raised or owns it | **Yes** |
| `issueStatusId` | `TODO` (not solved, the default) or `COMPLETE` (solved) |  |
| `type` | `short-term` (this week's list) or `long-term` (the parking lot) |  |
| `number` | The Issue's number, as shown in the app |  |
| `priorityNo` | `1` to `3` for a top-three priority, `999` for none |  |
| `meetingId` | The meeting it was raised in | if any |

Issue IDs are strings rather than UUIDs, so use `String!` for them in variables.

## Rocks and Milestones

`rocks` are 90-day priorities.

| Field | What it holds | Required |
| --- | --- | --- |
| `name` | The Rock |  |
| `desc` | Details, as HTML. Send `""` for none. | **Yes** |
| `userId` | Who owns it | **Yes** |
| `dueDate` | `YYYY-MM-DD` | **Yes** |
| `rockStatusId` | `ONTRACK`, `OFFTRACK`, `COMPLETE` (done) or `INCOMPLETE` (not done) | **Yes** |
| `type` | `company` or `personal` (an individual Rock) |  |
| `isArchived` | `true` once the Rock has been archived, usually at the end of its quarter |  |

A Rock can be shared with several teams, so it has no `teamId`. The link is in `teamsOnRocks`, with one record per team per Rock. To get one team's Rocks, look up the Rock IDs first:

```graphql
query TeamRocks($teamId: UUID!) {
  teamsOnRocks(filter: { teamId: { equalTo: $teamId }, stateId: { equalTo: "ACTIVE" } }) {
    nodes { rockId }
  }
}
```

Then fetch those Rocks, with their Milestones:

```graphql
query RocksById($ids: [UUID!]) {
  rocks(
    filter: { id: { in: $ids }, stateId: { equalTo: "ACTIVE" }, isArchived: { equalTo: false } }
    orderBy: DUE_DATE_ASC
  ) {
    nodes {
      id
      name
      dueDate
      rockStatus { name }
      user { firstName lastName }
      milestones(filter: { stateId: { equalTo: "ACTIVE" } }, orderBy: DUE_DATE_ASC) {
        nodes { name dueDate milestoneStatusId }
      }
    }
  }
}
```

When you create a Rock, create its `teamsOnRock` link in the same request, or it won't appear on any team. [Creating and updating data](https://www.success.co/docs/guides/api-creating-and-updating-data#make-several-changes-at-once) has the full example.

`milestones` are the steps of a Rock. Each has a `rockId`, `name`, `dueDate`, `userId` and `milestoneStatusId` (`TODO` or `COMPLETE`). `rockId`, `dueDate` and `userId` are required.

## Headlines

`headlines` are the good news and updates shared in meetings.

| Field | What it holds | Required |
| --- | --- | --- |
| `name`, `desc` | The Headline and its details (HTML) | `name`: **Yes** |
| `teamId` | The team it's shared with | **Yes** |
| `userId` | Who shared it | **Yes** |
| `headlineStatusId` | `DISCUSS` (not shared yet), `DISCUSSED` (shared) or `BACKLOG` |  |
| `isCascadingMessage` | `true` for a Cascading Message rather than a Headline |  |

## Scorecards

A Scorecard is made of two objects:

- **Measurables** (`dataFields`) are the rows: the number, who owns it and its goal.
- **Values** (`dataValues`) are the cells: one number per measurable per period.

| Measurable field | What it holds |
| --- | --- |
| `name`, `desc` | What's measured |
| `userId` | Who owns the number |
| `type` | How often it's measured: `WEEKLY`, `MONTHLY`, `QUARTERLY` or `ANNUALLY` |
| `unitType` | `number`, `percentage`, `currency`, `time` or `yes/no` |
| `goalTarget`, `unitComparison` | The goal, such as `150` with `>=`. Comparisons: `>=`, `<=`, `=`, `>`, `<`. A range uses `goalTargetEnd` too. |
| `goalCurrency` | The currency symbol for `currency` measurables, such as `$` |
| `dataFieldStatusId` | `ACTIVE`, or `ARCHIVED` once archived |
| `formula` | Set when the number is calculated from other measurables |

Like Rocks, measurables can be on several teams. The link is in `teamsOnDataFields`, with a `teamId` and a `dataFieldId`.

| Value field | What it holds | Required |
| --- | --- | --- |
| `dataFieldId` | The measurable it belongs to | **Yes** |
| `startDate` | The first day of the period, `YYYY-MM-DD` (see below) | **Yes** |
| `value` | The number, sent as a string, such as `"42"` or `"98.5"` |  |
| `note` | A note on this value |  |
| `customGoalTarget` | A different goal for just this period |  |

`startDate` must be the exact start of the measurable's period, or the value is refused:

| Measurable type | startDate must be |
| --- | --- |
| `WEEKLY` | A Monday, such as `2026-11-09` for the week of 12 November |
| `MONTHLY` | The 1st of the month |
| `QUARTERLY` | The first day of one of your company's quarters (by default 1 January, 1 April, 1 July and 1 October; your company may use different dates) |
| `ANNUALLY` | 1 January |

There's one value per measurable per period. To change a number that's already there, update it rather than creating another. [Recipes](https://www.success.co/docs/guides/api-recipes#send-a-scorecard-number-every-week) shows the full pattern.

## Meetings

Meetings come in two parts:

- **`meetingInfos`** are the recurring meetings you set up, such as a team's weekly Level 10 Meeting™. Each has a `name`, a `teamId`, an `ownerUserId` and the agenda it follows (`meetingAgenda`).
- **`meetings`** are each time it takes place, with its `date`, `meetingInfoId`, `meetingStatusId` (`NOT-STARTED`, `STARTED`, `PAUSED` or `FINISHED`), `startTime`, `endTime` and `averageRating`.

To-dos, Issues and Headlines raised in a meeting carry its `meetingId`, so you can list what came out of one:

```graphql
query MeetingOutcomes($meetingId: UUID!) {
  meeting(id: $meetingId) {
    date
    averageRating
    todos(filter: { stateId: { equalTo: "ACTIVE" } }) { nodes { name user { firstName } } }
    issues(filter: { stateId: { equalTo: "ACTIVE" } }) { nodes { name issueStatusId } }
  }
}
```

## Comments

`comments` are the comments on Rocks, To-dos, Issues, Headlines, Scorecard measurables and processes. Each has:

- `objectId`: the ID of the item it's on.
- `type`: what kind of item that is: `rocks`, `todos`, `issues`, `headlines`, `dataFields` (Scorecard measurables) or `processes`.
- `text`: the comment, as HTML.
- `userId`: who wrote it.

To get the comments on an Issue:

```graphql
query IssueComments($issueId: String!) {
  comments(
    filter: { objectId: { equalTo: $issueId }, type: { equalTo: "issues" }, stateId: { equalTo: "ACTIVE" } }
    orderBy: CREATED_AT_ASC
  ) {
    nodes { text createdAt user { firstName lastName } }
  }
}
```

To add one, create a `comment` with `objectId`, `type`, `text`, `userId` and `companyId`.

## Status values

Statuses are short IDs. Their display names, as the app shows them, are in a list for each kind, such as `rockStatuses { nodes { id name } }`.

| Field | Values |
| --- | --- |
| `todoStatusId` | `TODO` (To-do), `COMPLETE` (Done) |
| `issueStatusId` | `TODO` (Not solved), `COMPLETE` (Solved) |
| `rockStatusId` | `ONTRACK` (On-track), `OFFTRACK` (Off-track), `COMPLETE` (Done), `INCOMPLETE` (Not done) |
| `milestoneStatusId` | `TODO` (To-do), `COMPLETE` (Complete) |
| `headlineStatusId` | `DISCUSS` (Not shared), `DISCUSSED` (Shared), `BACKLOG` (Backlog) |
| `meetingStatusId` | `NOT-STARTED`, `STARTED`, `PAUSED`, `FINISHED` |
| `dataFieldStatusId` | `ACTIVE`, `ARCHIVED` |
| `userStatusId` | `ACTIVE`, `INACTIVE` |
| `stateId` (all objects) | `ACTIVE`, `DELETED` |

## Everything else

The API also covers the V/TO™ (`visions` and their entities), the Accountability Chart™ (`accCharts`, `accChartSeats`), processes, the People Analyzer™, SWOT items and more. These follow the same patterns, and their fields are listed in the full schema.

[Browse the full schema](https://studio.apollographql.com/public/Successco-API/variant/current/home)
