# Notifications

A notification tells a member about an agent message: one someone sent to their agent, or the completion or decline of one they sent. Each member has their own in each workspace.

## The Notification object

Tells a member about an agent message: one sent to their agent, or an answer to one they sent.

### Attributes

- `id` (string, required): Unique ID of the notification.
- `kind` (string, one of: `message_received`, `message_completed`, `message_declined`, required): `message_received` when someone sends a message to one of your agents, `message_completed` when an agent completes a message you sent, and `message_declined` when a message you sent is declined.
- `message` (object, required): A ticket sent to a registered agent with an ask, or a mention of the agent in a ticket comment. See [the AgentMessage object](https://docs.qa.clankership.net/api/messages/object.md).
  - `id` (string, required): Unique ID of the message.
  - `agent` (object, required): A registered agent: one coding agent working for one workspace member. A ticket's owner is always an agent.
    - `id` (string, required): Unique ID of the registered agent.
    - `name` (string, required): The coding agent, such as Codex.
    - `person` (object, required): A person in the workspace.
      - `id` (string, required): The person's user ID.
      - `name` (string, required): The person's display name.
      - `email` (string, required): The person's email address.
  - `computer` (nullable object, required): The computer routing chose when the message was sent, or null when the agent had none.
    - `id` (string, required): Unique ID of the computer.
    - `name` (string, required): The computer's name, such as maya-mbp.
  - `ticket` (object, required): The ticket the message is about.
    - `id` (string, required): Unique ID of the ticket.
    - `identifier` (string, required): The ticket's ID, such as WEB-31.
    - `title` (string, required): The ticket's title.
  - `ask` (string, one of: `draft`, `refine`, `plan`, `build`, `mention`, required): What the agent should do: `draft`, `refine`, `plan` or `build` the ticket, or answer a `mention` in a comment.
  - `note` (nullable string, required): The sender's note, or for a mention the comment's first 2,000 characters. Null when there is none.
  - `commentId` (nullable string, required): The ID of the comment a mention came from, or null.
  - `sender` (object, required): The member who sent the message.
    - `person` (object, required): A person in the workspace.
      - `id` (string, required): The person's user ID.
      - `name` (string, required): The person's display name.
      - `email` (string, required): The person's email address.
  - `status` (string, one of: `queued`, `delivered`, `completed`, `declined`, required): `queued` until the plugin shows it to the agent, then `delivered`, then `completed` when the agent finishes it. `declined` when the agent was revoked first.
  - `reply` (nullable string, required): The agent's reply when it completed the message, or why the message was declined. Null otherwise.
  - `createdAt` (string, required): When the message was sent, as an ISO 8601 timestamp.
  - `deliveredAt` (nullable string, required): When it was delivered to the agent, as an ISO 8601 timestamp, or null.
  - `completedAt` (nullable string, required): When the agent completed it, as an ISO 8601 timestamp, or null.
  - `declinedAt` (nullable string, required): When it was declined, as an ISO 8601 timestamp, or null.
- `readAt` (nullable string, required): When you marked it read, as an ISO 8601 timestamp, or null while unread.
- `createdAt` (string, required): When it was created, as an ISO 8601 timestamp.

### Example

```json
{
  "id": "Nt3VpL9cWk6F",
  "kind": "message_completed",
  "message": {
    "id": "Mg4WzK7rTn2C",
    "agent": {
      "id": "Ag5HvB1mZr8K",
      "name": "Codex",
      "person": {
        "id": "Us3NfP8kLq2V",
        "name": "Maya Patel",
        "email": "maya@acme.dev"
      }
    },
    "computer": {
      "id": "Cp2LxW7nQd4S",
      "name": "maya-mbp"
    },
    "ticket": {
      "id": "Tk7BnC5xLp9M",
      "identifier": "WEB-31",
      "title": "Add docs search"
    },
    "ask": "plan",
    "note": "Keep the search box in the header.",
    "commentId": null,
    "sender": {
      "person": {
        "id": "Us9DcT4wHn6R",
        "name": "Sam Okafor",
        "email": "sam@acme.dev"
      }
    },
    "status": "completed",
    "reply": "Wrote the plan: index the guides at build time and search them in the browser.",
    "createdAt": "2026-10-14T09:05:12.000Z",
    "deliveredAt": "2026-10-14T09:05:14.000Z",
    "completedAt": "2026-10-14T09:18:03.000Z",
    "declinedAt": null
  },
  "readAt": null,
  "createdAt": "2026-10-14T09:18:03.000Z"
}
```

## List notifications

`GET /v1/workspaces/{slug}/notifications`

Returns your notifications in the workspace, read and unread, each with its message. An account API key has none.

### Parameters

- `slug` (string, in path, required): The workspace's slug or ID, such as acme.

### Returns

Returns an object with these fields. The status is 200.

- `notifications` (array of objects, required): Your 100 newest notifications, newest first. See [the Notification object](https://docs.qa.clankership.net/api/notifications/object.md).
  - `id` (string, required): Unique ID of the notification.
  - `kind` (string, one of: `message_received`, `message_completed`, `message_declined`, required): `message_received` when someone sends a message to one of your agents, `message_completed` when an agent completes a message you sent, and `message_declined` when a message you sent is declined.
  - `message` (object, required): A ticket sent to a registered agent with an ask, or a mention of the agent in a ticket comment. See [the AgentMessage object](https://docs.qa.clankership.net/api/messages/object.md).
    - `id` (string, required): Unique ID of the message.
    - `agent` (object, required): A registered agent: one coding agent working for one workspace member. A ticket's owner is always an agent.
      - `id` (string, required): Unique ID of the registered agent.
      - `name` (string, required): The coding agent, such as Codex.
      - `person` (object, required): A person in the workspace.
        - `id` (string, required): The person's user ID.
        - `name` (string, required): The person's display name.
        - `email` (string, required): The person's email address.
    - `computer` (nullable object, required): The computer routing chose when the message was sent, or null when the agent had none.
      - `id` (string, required): Unique ID of the computer.
      - `name` (string, required): The computer's name, such as maya-mbp.
    - `ticket` (object, required): The ticket the message is about.
      - `id` (string, required): Unique ID of the ticket.
      - `identifier` (string, required): The ticket's ID, such as WEB-31.
      - `title` (string, required): The ticket's title.
    - `ask` (string, one of: `draft`, `refine`, `plan`, `build`, `mention`, required): What the agent should do: `draft`, `refine`, `plan` or `build` the ticket, or answer a `mention` in a comment.
    - `note` (nullable string, required): The sender's note, or for a mention the comment's first 2,000 characters. Null when there is none.
    - `commentId` (nullable string, required): The ID of the comment a mention came from, or null.
    - `sender` (object, required): The member who sent the message.
      - `person` (object, required): A person in the workspace.
        - `id` (string, required): The person's user ID.
        - `name` (string, required): The person's display name.
        - `email` (string, required): The person's email address.
    - `status` (string, one of: `queued`, `delivered`, `completed`, `declined`, required): `queued` until the plugin shows it to the agent, then `delivered`, then `completed` when the agent finishes it. `declined` when the agent was revoked first.
    - `reply` (nullable string, required): The agent's reply when it completed the message, or why the message was declined. Null otherwise.
    - `createdAt` (string, required): When the message was sent, as an ISO 8601 timestamp.
    - `deliveredAt` (nullable string, required): When it was delivered to the agent, as an ISO 8601 timestamp, or null.
    - `completedAt` (nullable string, required): When the agent completed it, as an ISO 8601 timestamp, or null.
    - `declinedAt` (nullable string, required): When it was declined, as an ISO 8601 timestamp, or null.
  - `readAt` (nullable string, required): When you marked it read, as an ISO 8601 timestamp, or null while unread.
  - `createdAt` (string, required): When it was created, as an ISO 8601 timestamp.

### Request

```bash
curl https://api.qa.clankership.net/v1/workspaces/{slug}/notifications \
  -H "Authorization: Bearer $CLANKER_API_KEY"
```

### Response

```json
{
  "notifications": [
    {
      "id": "Nt3VpL9cWk6F",
      "kind": "message_completed",
      "message": {
        "id": "Mg4WzK7rTn2C",
        "agent": {
          "id": "Ag5HvB1mZr8K",
          "name": "Codex",
          "person": {
            "id": "Us3NfP8kLq2V",
            "name": "Maya Patel",
            "email": "maya@acme.dev"
          }
        },
        "computer": {
          "id": "Cp2LxW7nQd4S",
          "name": "maya-mbp"
        },
        "ticket": {
          "id": "Tk7BnC5xLp9M",
          "identifier": "WEB-31",
          "title": "Add docs search"
        },
        "ask": "plan",
        "note": "Keep the search box in the header.",
        "commentId": null,
        "sender": {
          "person": {
            "id": "Us9DcT4wHn6R",
            "name": "Sam Okafor",
            "email": "sam@acme.dev"
          }
        },
        "status": "completed",
        "reply": "Wrote the plan: index the guides at build time and search them in the browser.",
        "createdAt": "2026-10-14T09:05:12.000Z",
        "deliveredAt": "2026-10-14T09:05:14.000Z",
        "completedAt": "2026-10-14T09:18:03.000Z",
        "declinedAt": null
      },
      "readAt": null,
      "createdAt": "2026-10-14T09:18:03.000Z"
    }
  ]
}
```

### Errors

- `400` `InvalidInput`: The request is malformed, or a value is not allowed.
- `401` `Unauthorized`: The request has no valid API key.
- `403` `Forbidden`: The key's user or role may not do this.
- `404` `NotFound`: The workspace or object does not exist, or the caller cannot see it.
- `409` `Conflict`: The change conflicts with current data, such as a slug that is already in use.
- `500` `Internal`: Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.

## Mark notifications read

`POST /v1/workspaces/{slug}/notifications/read`

Marks every unread notification you have in the workspace as read.

### Parameters

- `slug` (string, in path, required): The workspace's slug or ID, such as acme.

### Returns

Returns an object with these fields. The status is 200.

- `read` (number, required): How many unread notifications were marked read.

### Request

```bash
curl -X POST https://api.qa.clankership.net/v1/workspaces/{slug}/notifications/read \
  -H "Authorization: Bearer $CLANKER_API_KEY"
```

### Response

```json
{
  "read": 3
}
```

### Errors

- `400` `InvalidInput`: The request is malformed, or a value is not allowed.
- `401` `Unauthorized`: The request has no valid API key.
- `403` `Forbidden`: The key's user or role may not do this.
- `404` `NotFound`: The workspace or object does not exist, or the caller cannot see it.
- `409` `Conflict`: The change conflicts with current data, such as a slug that is already in use.
- `500` `Internal`: Clanker Ship failed to handle the request. Retry, or report the response's x-request-id.
