---
title: "POST /projects"
method: POST
path: "/projects"
tags: ["Projects"]
---

# POST /projects

`POST /projects`

## Request

- Base URL: `https://api.primitive.dev/v1`
- URL: `https://api.primitive.dev/v1/projects`
- Auth: HTTP bearer

Requires a current human organization membership. Machine credentials are refused. Results are scoped to current project access. No local paths or existing conversation history are shared.

## Headers

- `Idempotency-Key` string

## Request body

- ProjectsCreateProjectInput
  - `request_id` string, uuid, required
  - `name` string, required
  - `description` string
  - `repository` string, nullable
  - `color` string, required
  - `members` object[], required
    - `user_id` string, uuid, required
    - `recipient` union, required
      - object
        - `kind` 'work_email', required
      - object
        - `kind` 'agent', required
        - `address` string, email, required
      - object
        - `kind` 'private_agent', required
  - `agent_addresses` string[], required

## Response `200`

Success

- object
  - `success` true, required
  - `data` ProjectsCreateProjectResult, required
    - `id` string, uuid, required
    - `name` string, required
    - `description` string, required
    - `repository` string, nullable, required
    - `color` string, required
    - `version` integer, required
    - `members` object[], required
      - `user_id` string, uuid, required
      - `name` string, required
      - `work_email` string, email, nullable, required
      - `role` 'owner' | 'admin' | 'member' | 'restricted', required
      - `role_name` string, required
      - `role_id` string, uuid, nullable, required: The id of the person's own template or custom role, as GET /v1/roles lists it and PUT /v1/members/{id}/role accepts. Null when they have none: a built-in role, or (with role restricted) access from groups only.
      - `agents` object[], required
        - `id` string, uuid, required
        - `address` string, email, required
        - `name` string, required
      - `recipient` union, required
        - object
          - `kind` 'work_email', required
        - object
          - `kind` 'agent', required
          - `address` string, email, required
        - object
          - `kind` 'private_agent', required
      - `destination` string, email, nullable, required
      - `recipient_available` boolean, required
    - `agents` object[], required
      - `id` string, uuid, required
      - `address` string, email, required
      - `name` string, required
    - `access` object, required
      - `can_manage` boolean, required
      - `can_invite` boolean, required

## Other responses

- `400`: Invalid request parameters
- `401`: Invalid or missing API key
- `403`: Authenticated caller lacks permission for the operation
- `404`: Resource not found
- `409`: The request conflicts with the current state of the resource
- `429`: Rate limit exceeded. The `ratelimit-*` headers describe the limiter that rejected this request, with its own limit and window, not the API budget that successful responses report. A limiter that reports only a wait sends `Retry-After` alone.
- `503`: directory_limit: the organization agent directory is larger than projects can read. Narrow the directory before retrying.

## Changes

> 32 revisions in range; 1 not diffed.

- **2026-11-03** `bce409c97acb`: 217 warning
  - added the new `access_mode_unavailable` enum value to the `error/code` response property for the response status `400`
  - added the new `access_mode_unavailable` enum value to the `error/code` response property for the response status `401`
  - added the new `access_mode_unavailable` enum value to the `error/code` response property for the response status `403`
  - added the new `access_mode_unavailable` enum value to the `error/code` response property for the response status `404`
  - …213 more
  - …this revision’s changelog is incomplete
- **2026-10-21** `0360ea8d4f3d`: 1 breaking, 78 warning, 2 info
  - added `subschema #3` to the `data/members/items/recipient` response property `oneOf` list for the response status `200`
  - added the new `agent_changed` enum value to the `error/code` response property for the response status `400`
  - added the new `agent_changed` enum value to the `error/code` response property for the response status `401`
  - added the new `agent_changed` enum value to the `error/code` response property for the response status `403`
  - …77 more
- **2026-10-21** `5279a7bed7ac`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/primitive/apis/primitive-api/changes/projects/post.md)

---

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