> ## Documentation Index
> Fetch the complete documentation index at: https://docs.corsair.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# API

> API reference for Teamcamp: every `teamcamp.api.*` operation with input and output types.

Every `teamcamp.api.*` operation is listed below with parameter shapes and return types from the plugin Zod schemas.

> [!NOTE]
>
> **New to Corsair?** See [API access](https://docs.corsair.dev/concepts/api.md), [authentication](https://docs.corsair.dev/concepts/auth.md), and [error handling](https://docs.corsair.dev/concepts/error-handling).

## Account

### verify

`account.verify`

Read the workspace the key belongs to, which also confirms the key is valid

**Risk:** `read`

```ts theme={null}
await corsair.teamcamp.api.account.verify({});
```

**Input:** *empty object*

Reads the workspace the key belongs to. A bad key answers 403 here, which is the one call where that status really does mean the key.

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `workspaceId` | `string` | Yes | — |
| `workspaceName` | `string \| null` | No | — |
| `createdBy` | `string \| null` | No | — |

***

## Customers

### list

`customers.list`

List the customers a project can be billed to, with their clients

**Risk:** `read`

```ts theme={null}
await corsair.teamcamp.api.customers.list({});
```

**Input:** *empty object*

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `customers` | `object[]` | Yes | — |

> [accordion] customers full type
>
> ```ts theme={null}
> {
>   customerId: string,
>   address?: string | null,
>   firstName?: string | null,
>   lastName?: string | null,
>   email?: string | null,
>   companyName?: string | null,
>   phone?: string | null,
>   clients?: {
>     clientId?: string | null,
>     name?: string | null
>   }[] | null
> }[]
> ```

***

## Groups

### list

`groups.list`

List the task groups of a project, by id and name

**Risk:** `read`

```ts theme={null}
await corsair.teamcamp.api.groups.list({ projectId: '<project id>' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `projectId` | `string` | Yes | The project to list the task groups of. |

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `groups` | `object[]` | Yes | — |

> [accordion] groups full type
>
> ```ts theme={null}
> {
>   groupId: string,
>   groupName?: string | null,
>   projectId?: string | null
> }[]
> ```

***

## Projects

### create

`projects.create`

Create a project, optionally from a template and with a customer and dates

**Risk:** `write`

```ts theme={null}
await corsair.teamcamp.api.projects.create({ projectName: 'Website Redesign', customerId: '<customer id>', startDate: '2026-11-30', dueDate: '2026-12-31' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `projectName` | `string` | Yes | The project name. |
| `customerId` | `string` | No | The customer to bill the project to. |
| `startDate` | `string` | No | The project start date. |
| `dueDate` | `string` | No | The project due date. |
| `templateId` | `string` | No | A project template to copy the statuses and groups from. |

Only `projectName` is required. A `templateId` copies the template's statuses and groups into the new project.

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `projectId` | `string` | Yes | — |
| `projectName` | `string \| null` | No | — |
| `workspaceId` | `string \| null` | No | — |
| `ownerId` | `string \| null` | No | — |
| `description` | `string \| null` | No | — |
| `customerId` | `string \| null` | No | — |
| `startDate` | `string \| null` | No | — |
| `dueDate` | `string \| null` | No | — |
| `favoriteUsers` | `string[] \| null` | No | — |
| `projectUsers` | `string[] \| null` | No | — |
| `statusEnable` | `boolean \| null` | No | — |
| `estimate` | `boolean \| null` | No | — |
| `priority` | `boolean \| null` | No | — |
| `archived` | `boolean \| null` | No | — |
| `status` | `object[] \| null` | No | — |

> [accordion] status full type
>
> ```ts theme={null}
> {
>   Name?: string | null,
>   Type?: number | null,
>   _id?: string | null,
>   Index?: number | null,
>   Default?: boolean | null
> }[] | null
> ```

***

### delete

`projects.delete`

Delete a project. It is archived rather than erased: it leaves the project list, but a read by id still returns it marked archived

**Risk:** `destructive`

```ts theme={null}
await corsair.teamcamp.api.projects.delete({ projectId: '<project id>' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `projectId` | `string` | Yes | The project to delete. |

This archives the project rather than erasing it. It leaves the project list, but a read by id still returns it with `archived: true`, so this is destructive but the record survives.

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `archived` | `boolean` | Yes | — |
| `projectId` | `string` | Yes | — |
| `message` | `string` | Yes | — |

***

### get

`projects.get`

Read one project: its members, owner, dates and workflow statuses, which a task create needs for its status id

**Risk:** `read`

```ts theme={null}
await corsair.teamcamp.api.projects.get({ projectId: '<project id>' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `projectId` | `string` | Yes | The project id, as the project list reports it. |

The workflow statuses in `status` are what a task create needs for `statusId`, and `projectUsers` is what it needs for `taskUsers`.

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `projectId` | `string` | Yes | — |
| `projectName` | `string \| null` | No | — |
| `workspaceId` | `string \| null` | No | — |
| `ownerId` | `string \| null` | No | — |
| `description` | `string \| null` | No | — |
| `customerId` | `string \| null` | No | — |
| `startDate` | `string \| null` | No | — |
| `dueDate` | `string \| null` | No | — |
| `favoriteUsers` | `string[] \| null` | No | — |
| `projectUsers` | `string[] \| null` | No | — |
| `statusEnable` | `boolean \| null` | No | — |
| `estimate` | `boolean \| null` | No | — |
| `priority` | `boolean \| null` | No | — |
| `archived` | `boolean \| null` | No | — |
| `status` | `object[] \| null` | No | — |

> [accordion] status full type
>
> ```ts theme={null}
> {
>   Name?: string | null,
>   Type?: number | null,
>   _id?: string | null,
>   Index?: number | null,
>   Default?: boolean | null
> }[] | null
> ```

***

### list

`projects.list`

List the projects in the workspace, by id and name

**Risk:** `read`

```ts theme={null}
await corsair.teamcamp.api.projects.list({});
```

**Input:** *empty object*

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `projects` | `object[]` | Yes | — |

> [accordion] projects full type
>
> ```ts theme={null}
> {
>   projectId: string,
>   projectName?: string | null
> }[]
> ```

***

### update

`projects.update`

Change a project name, description, dates or customer

**Risk:** `write`

```ts theme={null}
await corsair.teamcamp.api.projects.update({ projectId: '<project id>', projectName: 'Website Redesign v2' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `projectId` | `string` | Yes | The project to update. |
| `projectName` | `string` | No | The new project name. |
| `description` | `string` | No | The new description. |
| `startDate` | `string` | No | The new start date. |
| `dueDate` | `string` | No | The new due date. |
| `customerId` | `string` | No | The customer to bill the project to. |

Give at least one of `projectName`, `description`, `startDate`, `dueDate` or `customerId`.

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `projectId` | `string` | Yes | — |
| `projectName` | `string \| null` | No | — |
| `workspaceId` | `string \| null` | No | — |
| `ownerId` | `string \| null` | No | — |
| `description` | `string \| null` | No | — |
| `customerId` | `string \| null` | No | — |
| `startDate` | `string \| null` | No | — |
| `dueDate` | `string \| null` | No | — |
| `favoriteUsers` | `string[] \| null` | No | — |
| `projectUsers` | `string[] \| null` | No | — |
| `statusEnable` | `boolean \| null` | No | — |
| `estimate` | `boolean \| null` | No | — |
| `priority` | `boolean \| null` | No | — |
| `archived` | `boolean \| null` | No | — |
| `status` | `object[] \| null` | No | — |

> [accordion] status full type
>
> ```ts theme={null}
> {
>   Name?: string | null,
>   Type?: number | null,
>   _id?: string | null,
>   Index?: number | null,
>   Default?: boolean | null
> }[] | null
> ```

***

## Tasks

### create

`tasks.create`

Create a task in a project, with a priority, due date, assignees, group, status, milestone, estimate and attachments

**Risk:** `write`

```ts theme={null}
await corsair.teamcamp.api.tasks.create({ projectId: '<project id>', taskName: 'Draft the launch announcement', priority: 'high', dueDate: '2026-12-15' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `projectId` | `string` | Yes | The project the task belongs to. |
| `taskName` | `string` | Yes | The task name. |
| `description` | `string` | No | The task description. |
| `priority` | `none \| urgent \| high \| medium \| low` | No | The task priority. Omit it for no priority. The project must have task priorities turned on in Teamcamp, or Teamcamp answers 400 "Not enable priority in your project." |
| `dueDate` | `string` | No | The task due date. |
| `groupId` | `string` | No | The task group to place it in. |
| `taskUsers` | `string[]` | No | User ids to assign as the task assignees. |
| `statusId` | `string` | No | The workflow status id, as a project read lists it under `status`. Teamcamp does not check it, so a wrong id is saved as given. |
| `milestoneId` | `number` | No | The milestone id, when the project has milestones. |
| `estimateTime` | `number` | No | The estimated hours for the task. The project must have estimates turned on in Teamcamp, or Teamcamp answers 400. |
| `files` | `object[]` | No | Files to attach, each with its type, url, name and a human-readable size such as "12 KB". |

The name field is sent as `taskName`, which is what the API accepts; the published spec calls it `name` and that is rejected.

> [accordion] files full type
>
> ```ts theme={null}
> {
>   fileType: string,
>   href: string,
>   name: string,
>   size: string
> }[]
> ```

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `taskId` | `string` | Yes | — |
| `taskName` | `string \| null` | No | — |
| `projectId` | `string \| null` | No | — |
| `status` | `boolean \| null` | No | — |
| `statusId` | `string \| null` | No | — |
| `groupId` | `string \| null` | No | — |
| `group` | `string \| null` | No | — |
| `taskUsers` | `object[] \| null` | No | — |
| `subscribers` | `string[] \| null` | No | — |
| `description` | `string \| null` | No | — |
| `dueDate` | `string \| null` | No | — |
| `estimateTime` | `number \| null` | No | — |
| `milestoneId` | `number \| null` | No | — |
| `labels` | `string[] \| null` | No | — |
| `files` | `Record<string, JsonValue>[] \| null` | No | — |
| `comments` | `object[] \| null` | No | — |
| `createdBy` | `string \| null` | No | — |
| `createdTime` | `string \| null` | No | — |
| `updatedBy` | `string \| null` | No | — |
| `updatedTime` | `string \| null` | No | — |
| `links` | `JsonValue[] \| null` | No | — |

> [accordion] taskUsers full type
>
> ```ts theme={null}
> {
>   taskUserId?: string | null
> }[] | null
> ```

> [accordion] comments full type
>
> ```ts theme={null}
> {
>   _id?: string | null,
>   commentId?: string | null,
>   content?: string | null,
>   CreatedBy?: string | null,
>   UpdatedBy?: string | null,
>   CreatedTime?: string | null,
>   UpdatedTime?: string | null,
>   Type?: number | null
> }[] | null
> ```

***

### get

`tasks.get`

Read one task, with its assignees, labels, files and comments

**Risk:** `read`

```ts theme={null}
await corsair.teamcamp.api.tasks.get({ taskId: '<task id>' });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `taskId` | `string` | Yes | The task id. |

Comments on the task use PascalCase fields (`_id`, `CreatedBy`, `CreatedTime`, `Type`), unlike the rest of the answer.

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `taskId` | `string` | Yes | — |
| `taskName` | `string \| null` | No | — |
| `projectId` | `string \| null` | No | — |
| `status` | `boolean \| null` | No | — |
| `statusId` | `string \| null` | No | — |
| `groupId` | `string \| null` | No | — |
| `group` | `string \| null` | No | — |
| `taskUsers` | `object[] \| null` | No | — |
| `subscribers` | `string[] \| null` | No | — |
| `description` | `string \| null` | No | — |
| `dueDate` | `string \| null` | No | — |
| `estimateTime` | `number \| null` | No | — |
| `milestoneId` | `number \| null` | No | — |
| `labels` | `string[] \| null` | No | — |
| `files` | `Record<string, JsonValue>[] \| null` | No | — |
| `comments` | `object[] \| null` | No | — |
| `createdBy` | `string \| null` | No | — |
| `createdTime` | `string \| null` | No | — |
| `updatedBy` | `string \| null` | No | — |
| `updatedTime` | `string \| null` | No | — |
| `links` | `JsonValue[] \| null` | No | — |

> [accordion] taskUsers full type
>
> ```ts theme={null}
> {
>   taskUserId?: string | null
> }[] | null
> ```

> [accordion] comments full type
>
> ```ts theme={null}
> {
>   _id?: string | null,
>   commentId?: string | null,
>   content?: string | null,
>   CreatedBy?: string | null,
>   UpdatedBy?: string | null,
>   CreatedTime?: string | null,
>   UpdatedTime?: string | null,
>   Type?: number | null
> }[] | null
> ```

***

### list

`tasks.list`

List the tasks of a project, optionally only the completed or only the open ones

**Risk:** `read`

```ts theme={null}
await corsair.teamcamp.api.tasks.list({ projectId: '<project id>', complete: false });
```

**Input**

| Name | Type | Required | Description |
| - | - | - | - |
| `projectId` | `string` | Yes | The project to list tasks from. Required by the API. |
| `complete` | `boolean` | No | True returns only completed tasks, false only open ones. Omit it for both. |

`projectId` is required; the API answers 400 "ProjectId is required" without it. `complete: true` returns only finished tasks, `false` only open ones.

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `tasks` | `object[]` | Yes | — |

> [accordion] tasks full type
>
> ```ts theme={null}
> {
>   taskId: string,
>   taskName?: string | null,
>   status?: boolean | null,
>   statusId?: string | null,
>   createdAt?: string | null,
>   updatedAt?: string | null,
>   id?: string | null
> }[]
> ```

***

## Users

### list

`users.list`

List the workspace members, with their role, timezone and last seen time

**Risk:** `read`

```ts theme={null}
await corsair.teamcamp.api.users.list({});
```

**Input:** *empty object*

The answer also carries each member's timezone, date format and last seen time, which the published spec does not mention.

**Output**

| Name | Type | Required | Description |
| - | - | - | - |
| `users` | `object[]` | Yes | — |

> [accordion] users full type
>
> ```ts theme={null}
> {
>   id: string,
>   name?: string | null,
>   email?: string | null,
>   phone?: string | null,
>   timezone?: string | null,
>   dateFormat?: string | null,
>   profile_photo?: string | null,
>   isOwner?: boolean | null,
>   isAdmin?: boolean | null,
>   lastSeen?: string | null
> }[]
> ```

***


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.