# POST /api/v2/drive-items

Create a drive item

- MCP id: drive-items.store
- Scope: api:write:project_drive
- Scope: api:write:customer_drive
- Scope: api:write:organization_drive
- Scope: api:write:user_drive
- Permission: project_drive::create
- Rate cost: 1 unit, write bucket. A write costs the same whatever `view` you ask for.
- Cache-Control: private, no-store

Creates a bodyless document item under a project, a customer, the organisation drive or the caller's own drive, and returns it with a `Location` header.

The drive is named by the `owner_type`/`owner_id` pair (one of the few flat creates that accepts a type and id pair), and a record the caller cannot read is refused exactly as a nonexistent one is. For `owner_type=organization` there is no `owner_id` to send: it is always your own organisation. Give the item a body afterwards by POSTing to `/api/v2/drive-documents`; this endpoint never accepts one, and it cannot upload a file. A `folder_id` must belong to the same owner and be a folder you can edit. The declared permission is `project_drive::create`; the other three drive prefixes apply by owner type, and the record rule is what actually decides.

## Parameters
- view (string, optional): Which field set to render.
- X-Request-Id (header, optional): A correlation id of your own. It is recorded in our logs next to the server's request id but never returned: the response header always carries the server's id. A value that does not match the pattern is discarded silently, never rejected.
- Idempotency-Key (header, optional): A caller-chosen key that makes this POST safe to retry. Replaying it returns the original response with Idempotency-Replayed: true.

## Request body
- owner_type (string, required): The project, customer, organisation or user whose drive this item lives in. An organisation-owned item renders as a bare {"id": N} reference.
- owner_id (integer, required): The project, customer, organisation or user whose drive this item lives in. An organisation-owned item renders as a bare {"id": N} reference.
- title (string ≤ 255, required): Item title.
- group (string or null ≤ 255, optional): Free-text grouping label shown in the drive tree.
- folder_id (integer or null → DriveFolder.id, optional): Folder this item sits in, or `null` at the drive root.
- tag_ids (array of integer → Tag.id ≤ 50, optional): Tags on this item. An item takes at most 50 tags, so the include lists them all. `tag_ids` replaces the whole set.

Unknown keys are refused with `422` validation-failed, naming the key.

## Response 201
- id (integer, required): Unique identifier.
- title (string ≤ 255, required): Item title.
- group (string or null ≤ 255, required): Free-text grouping label shown in the drive tree.
- kind (string, required): What this item is. Everything created through the API is a `document`; the other kinds come from uploads in plnnrly.
- source (string, required): Where the item came from: `builtin` for an editor document, `upload` for a file uploaded in plnnrly.
- folder_id (integer or null, required): Folder this item sits in, or `null` at the drive root.
- drive_folder (Ref or DriveFolderSummary or null, required): The folder this item sits in; absent for items at the drive root.
- owner_type (string, required): The kind of record `owner` points at; it says which branch of `owner` applies.
- owner_id (integer, required): The id of the record `owner` points at.
- owner (Ref or ProjectSummary or CustomerSummary or UserSummary, required): The project, customer, organisation or user whose drive this item lives in. An organisation-owned item renders as a bare {"id": N} reference.
- content_record_type (string or null, required): The kind of record `content_record` points at; it says which branch of `content_record` applies.
- content_record_id (integer or null, required): The id of the record `content_record` points at.
- content_record (Ref or null, required): The body this item points at: a drive document for an editor document, `null` for an item with no body yet. Renders as a bare {"id": N} reference; read the body from `GET /api/v2/drive-documents/{drive_document}`.
- order_column (integer, required, server-assigned): Sort position, assigned by the server. Positions count per drive and folder, so the sequence is only meaningful once the collection is narrowed to one drive and one folder. Reordering is not exposed in v2.0.
- created_by (integer or null, required, server-assigned): Author; always the authenticated user at create time. Null on legacy rows and where the author has since been deleted.
- archived_by (integer or null, required, server-assigned): The user who archived this item; set on delete and cleared on restore.
- inherits_permissions (boolean, required): Whether this item takes its permissions from its folder.
- general_access (string, required): Baseline sharing tier, consulted only while `inherits_permissions` is `false`.
- access (string or null, required): The calling user's effective access level on this item, after the permission for the owner type, the access inherited from folders and any per-item grant.
- created_at (timestamp (YYYY-MM-DDThh:mm:ssZ), required): Creation timestamp.
- updated_at (timestamp (YYYY-MM-DDThh:mm:ssZ), required): Last-write timestamp; use for incremental sync.
- deleted_at (timestamp (YYYY-MM-DDThh:mm:ssZ) or null, required): When this item was archived, or `null` while it is live.
- comments_count (integer ≥ 0, required): Comments on this item.
- files_count (integer ≥ 0, required): Files attached to this item, counting the attachments list in plnnrly, the single uploaded file and the images embedded in the document body.
- tags_count (integer ≥ 0, required): Tags on this item.
- links (DriveItemLinks, required)
  - self (url, required): The canonical URI of this record.
  - comments (url, required): Comments on this drive item.
  - files (url, required): Files stored on this drive item.
- tags (array of TagSummary ≤ 50, optional, only with include): Tags on this item. An item takes at most 50 tags, so the include lists them all. `tag_ids` replaces the whole set. Wrapped in `{ data, meta }`; `meta.truncated` says whether the cap was hit and `meta.count` is the full count.
  - id (integer, required): Unique identifier.
  - title (string ≤ 255, required): Tag title as shown in the UI.

## Errors
- 403 forbidden-by-policy | insufficient-permission | insufficient-token-scope: Forbidden.
- 409 idempotency-key-in-flight | idempotency-key-reused | state-conflict: Conflict.
- 415 unsupported-media-type: Unsupported media type.
- 422 unprocessable-relationship | validation-failed: Unprocessable content.
- 400 idempotency-key-required | invalid-cursor | invalid-query-parameter | malformed-request | unsupported-parameter: Bad request.
- 401 token-expired | unauthenticated: Unauthenticated.
- 404 endpoint-not-found | resource-not-found: Not found.
- 406 not-acceptable: Not acceptable.
- 429 rate-limit-exceeded: Too many requests.
- 500 internal-error: Server error.
- 503 tenant-unavailable: Service unavailable.

## Example
```bash
curl -X POST \
  'https://<your-url>/api/v2/drive-items' \
  -H 'Authorization: Bearer <token>' \
  -H 'Accept: application/json' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: <key>' \
  -d '{
    "owner_type": "project",
    "owner_id": 1,
    "title": "Kick-off notes"
  }'
```
