---
title: "Create Captain"
method: POST
path: "/api/v1/captains"
tags: ["captains"]
---

# Create Captain

`POST /api/v1/captains`

## Request

- Base URL: `https://api.capy.ai`
- URL: `https://api.capy.ai/api/v1/captains`
- Auth: HTTP bearer

## Request body

- CreateCaptainRequest
  - `requestId` string, required
  - `projectId` string, required
  - `name` string, required
  - `brief` string: The Captain's first message from you: what it is for and what to start on. Absent, the Captain greets you and asks.
  - `model` ModelSelection
    - `modelId` string, required
    - `reasoningMode` 'none' | 'instant' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max'
    - `modes` object
      - `fast` boolean
      - `pro` boolean
      - `ultrafast` boolean
      - `daybreak` boolean
  - `avatar` CaptainAvatar
    - `kind` 'preset' | 'emoji', required
    - `value` string, required
    - `background` string, required
    - `image` string
  - `authorId` string: The active member of the key's organization who owns the Captain. A Captain needs a human owner, so a service key must name one; a personal key owns it itself when absent. A replayed `requestId` returns the existing Captain unchanged.

## Response `200`

Captain

- CaptainEncoded
  - `id` string, required
  - `projectId` string, nullable, required
  - `authorId` string, nullable, required
  - `previousAuthorId` string, nullable, required
  - `title` string, nullable, required
  - `titleCustom` boolean, required
  - `status` 'working' | 'waiting' | 'idle' | 'failed' | 'archived', required
  - `archived` boolean, required
  - `lastModelId` string, nullable, required
  - `linearIssue` ThreadLinearIssue, required
    - `key` string, required
    - `url` string, nullable, required
  - `pullRequestAuthor` 'user' | 'capy', nullable, required: Who authors this thread's pull requests on GitHub: `capy` for the Capy GitHub App, `user` for the thread's acting human. Null means the acting human's Git identity preference decides.
  - `usage` UsageTotalsEncoded, required
    - `llmCredits` union, required
      - number
      - 'Infinity' | '-Infinity' | 'NaN'
    - `imageCredits` union, required
      - number
      - 'Infinity' | '-Infinity' | 'NaN'
    - `vmCredits` union, required
      - number
      - 'Infinity' | '-Infinity' | 'NaN'
    - `totalCredits` union, required
      - number
      - 'Infinity' | '-Infinity' | 'NaN'
  - `createdAt` string, required
  - `updatedAt` string, required
  - `lastActivityAt` string, nullable, required
  - `hasUnreads` boolean, required
  - `mentionCount` integer, required
  - `owed` boolean, required
  - `needsYou` boolean
  - `ask` ThreadAsk
    - `key` string, required
    - `kind` 'conversation' | 'environment' | 'mcp' | 'credits' | 'desktop' | 'feedback' | 'terminal', required
    - `text` string, nullable, required
    - `causeKey` string, nullable, required
  - `crewNeedsYou` integer
  - `participated` boolean
  - `crewMentionCount` integer
  - `captain` ThreadCaptain
    - `jamId` string, required
    - `name` string, required
    - `avatar` CaptainAvatar, required
      - `kind` 'preset' | 'emoji', required
      - `value` string, required
      - `background` string, required
      - `image` string
  - `crewCount` integer
  - `member` boolean, required
  - `subscribed` boolean
  - `personal` boolean
  - `visibility` 'org' | 'private'
  - `name` string, required
  - `avatar` CaptainAvatar, required
    - `kind` 'preset' | 'emoji', required
    - `value` string, required
    - `background` string, required
    - `image` string
  - `description` string, nullable, required: A short public label saying whose Captain this is and what it covers, at most 140 characters of plain text, for attribution and discovery. Null when unset.

## Other responses

- `400`: capy/InvalidRequest | ModelSelection.Rejected
- `401`: capy/Unauthorized
- `402`: capy/PaidFeatureUnavailable
- `403`: capy/Forbidden
- `404`: capy/ProjectNotFound
- `429`: capy/RateLimited

## Changes

- **2026-10-31** `4477714a54f1`: 1 warning
  - added the new `terminal` enum value to the `ask/kind` response property for the response status `200`
- **2026-10-31** `e3be47264feb`: 1 info
  - added the optional property `ask` to the response with the `200` status
- **2026-10-29** `e613eb753cf8`: 1 breaking, 5 info
  - the `anyOf[#/components/schemas/ModelSelection.RejectedEncoded]/service` response's property type changed from `string` to no type for status `400`
  - added `#/components/schemas/UnsupportedMember, subschema #1` to the `anyOf[#/components/schemas/ModelSelection.RejectedEncoded]/service` response property `anyOf` list for the response status `400`
  - removed the `claude` enum value from the `anyOf[#/components/schemas/ModelSelection.RejectedEncoded]/service` response property for the response status `400`
  - removed the `codex` enum value from the `anyOf[#/components/schemas/ModelSelection.RejectedEncoded]/service` response property for the response status `400`
  - …2 more
- **2026-10-22** `76d1313f4197`: 1 info
  - added the new optional request property `model/modes/daybreak`
- **2026-10-19** `eb29d959f187`: 1 warning
  - added the new `claude` enum value to the `anyOf[#/components/schemas/ModelSelection.RejectedEncoded]/service` response property for the response status `400`

[Operation history](https://skmtc.dev/capy/apis/capy-api/changes/api/v1/captains/post.md)

---

[API](https://skmtc.dev/capy/apis/capy-api.md) - [All operations](https://skmtc.dev/capy/apis/capy-api/llms.txt) - [OpenAPI document](https://skmtc.dev/capy/apis/capy-api/revisions/4663f7dc4e39?raw)
