# How By Dawn is organised

> Organizations, projects, columns and tickets, how they fit together, and what that means for your code.

Before you write code against By Dawn, it helps to know the handful of things it's made of. This page
walks through them from the top down, and points out the details that trip people up.

In short: everything lives in one **organization**. Work is split into **projects**, and each
project is a board whose columns are called **statuses**. A **ticket** always sits in exactly one
column. The API is built around tickets: you read and write tickets and what's attached to them,
and you read the board around them.

This page describes them as the API sees them. For the same ideas in the app, see [Board and columns](https://docs.bydawn.com/board-and-columns/),
[Tickets and sub-tickets](https://docs.bydawn.com/tickets/), [Epics and milestones](https://docs.bydawn.com/epics-and-milestones/) and [Cycles](https://docs.bydawn.com/cycles/).

- Organization (`{orgId}`): Every path starts with /orgs/{orgId}. An API key belongs to one organization.
  - Project (`projectId`): A board. Its ticketPrefix starts every identifier (SAW-123).
    - Statuses (`statusId`): The board's columns, in order. Some carry a role.
    - Cycles (`cycleId`): Time-boxed iterations of this project.
    - Ticket (`ticketId`): Sits in exactly one status. Can have a parent (sub-tickets).
      - Comments (`commentId`): Oldest first. Reactions hang off them.
      - Relations (`relationId`): blocks, related or duplicate, to another ticket.
  - Labels (`labelId`): Shared by the organization's projects.
  - Users (`assigneeId`): Members. Not readable with an API key.

## Organization

Your API key belongs to one organization, and every request acts on it. That's why every path
starts with `/orgs/{orgId}`. You can read the ID from your access token, as
[Authentication](https://docs.bydawn.com/developers/authentication/#your-organization-id) shows.

## Projects and their boards

A project is one board of work, and `GET /projects` lists them. Each has a short prefix that
starts its tickets' names, like `SAW` in `SAW-123`. Most calls take a `projectId`.

**Statuses** are a board's columns, in the order they're shown. Ask for them with the project's
ID (`GET /statuses?projectId=…`), because a project can have its own columns. Without it you get
the organization's default board.

Teams rename and add columns, so By Dawn tags the few columns its workflow depends on with a **role**:
`backlog`, `todo` (shown as Planning), `building`, `review` and `completed`. A column a team adds
has no role. Roles matter to you in three places:

- A ticket you create without choosing a column lands in the `backlog` one.
- `GET /tickets?open=true` leaves out tickets in the `completed` column.
- Moving a ticket into the `building` column starts By Dawn's agent on it, which is why an API key
  isn't allowed to.

**Cycles** are a project's time-boxed iterations, like sprints (`GET /cycles?projectId=…`). A
ticket's `cycleId` says which one it's planned into.

## Tickets

A ticket has two names, and you'll use both:

| Field | Example | What it's for |
|---|---|---|
| `id` | `ticket-…` | Your code. Every API path takes it, and tickets refer to each other by it. |
| `identifier` | `SAW-123` | People. Show it in your UI and messages. To find a ticket by it, search: `GET /tickets?projectId=…&q=SAW-123` puts the exact match first. |

A ticket can have a parent (`parentTicketId`), which makes it a **sub-ticket**. A sub-ticket has
its own identifier, and also a `displayIdentifier` such as `SAW-123.1` that shows its parent.

Attached to each ticket you'll find:

- **Comments**, oldest first, with emoji reactions. See [Comment on a ticket](https://docs.bydawn.com/developers/recipes/comments/).
- **Relations** to other tickets: `blocks`, `related` or `duplicate`. To break work down, give
  the smaller tickets a parent instead.
- **Labels**, by `labelIds`. Labels belong to the organization, so every project shares them.
- **A team**, by `teamId`: the team that owns the ticket, one of the teams that work in its project. Changing it
  changes nothing else about the ticket. See [Organize work by team](https://docs.bydawn.com/developers/organize-work-by-team/).

Tickets are archived rather than deleted, so nothing disappears by accident. Archive one with
`POST /tickets/{ticketId}/archive`, and bring it back with `/unarchive`.

What an API key may and may not touch is listed once, in
[Authentication](https://docs.bydawn.com/developers/authentication/#what-a-key-cant-do).

## Missions

While By Dawn's agent works on a ticket, it follows a **mission**: steps such as a plan a person
approves, tests that must pass and By Dawn merging the pull request. The organization keeps a library
of steps and **mission templates** that decide which steps a new ticket starts with, and a project
can tighten them for itself. Missions aren't part of the public API yet, but a ticket that By Dawn
holds at a step names it in `heldAt`. See [Missions and templates](https://docs.bydawn.com/missions/).

A person starts the agent from the ticket ([Start a ticket](https://docs.bydawn.com/start-a-ticket/)) and answers it when a step waits for
them ([Checkpoints and debriefs](https://docs.bydawn.com/mission-checkpoints/)). The agent runs on your organization's own machines
([Remote agents and machines](https://docs.bydawn.com/remote-agents/)), with the model, skills and secrets your team sets up for it.

## Do and don't

**Do:**

- Store a ticket's `id`, and show people its `identifier`.
- Read a project's columns once with `GET /statuses` and keep their IDs. Find a column by its
  `role` rather than its name, because teams rename columns.

**Don't:**

- Build a ticket's ID or URL from its identifier. Search with `q` instead.
- Hard-code a column name such as "Done". Look for the `completed` role.

Source: https://docs.bydawn.com/how-saw-is-organised/
