# Create a category or subcategory

`POST https://api.cream-ai.de/api/v1/categories`

Creates a top-level category, or a subcategory with `parent_id` (only two levels). With `external_key` the request is safe to repeat: if a category with this key already exists (on any level, even with another `parent_id`), the response is `200` with that category and nothing is changed. The same name on the same level returns `409 category_exists` with `details.category_id`. A company can have at most 500 categories (main and subcategories together); creating one more returns `409 category_limit_reached` with `details.limit`.

Scopes: `categories:write`

## Parameters

- `Idempotency-Key` (header, required): Unique key of this write request (1–128 visible ASCII characters, e.g. a UUID). Retries with the same key return the stored response.

## Request body

- `name` (string, required): Name of the new category (trimmed; at most 80 characters, longer names are rejected).
- `parent_id` (nullable string): Id of a top-level category to create a subcategory; omit or null for a top-level category.
- `external_key` (nullable string): Optional key of the connected system. Repeating the request with the same key returns the existing category (200).

## Returns

- 200: A category with this external key already exists; it is returned unchanged.
- 201: The category was created.

## Errors

- 400: Invalid request (invalid_request, invalid_json, invalid_cursor, idempotency_key_required, invalid_idempotency_key, parent_not_found, max_depth_exceeded, narration_too_long, user_not_in_company, template_not_found, category_not_found, feedback_kind_unsupported, upload_not_found).
- 401: Missing, malformed, revoked or expired API key (unauthorized).
- 403: Not allowed (forbidden_scope, ip_not_allowed, company_inactive, api_not_enabled).
- 409: Conflict (category_exists, external_key_exists, external_key_conflict, category_limit_reached, idempotency_in_progress, version_conflict, previous_version_creating, film_deleted, not_cancellable, file_unavailable, storyboard_not_ready, storyboard_not_current, timeline_outdated, preview_in_progress, preview_not_ready, preview_unsupported, feedback_queue_full, feedback_not_cancellable, feedback_not_retryable, feedback_busy, revision_locked, film_not_ready, film_busy, no_open_comments, comments_not_open, correction_in_progress, upload_quota_exceeded, film_cancelled).
- 413: Request body too large (payload_too_large).
- 415: Request body is not JSON (unsupported_media_type).
- 422: Idempotency-Key reused with a different request (idempotency_mismatch).
- 429: Too many requests (rate_limited).
- 500: Internal error (internal). Quote the request id when you contact support.
- 503: Temporarily unavailable (service_unavailable). Retry later (after Retry-After seconds, if sent).

## Example request

```sh
curl -X POST "https://api.cream-ai.de/api/v1/categories" \
  -H "Authorization: Bearer $MINT_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "MKT101 Marketing basics",
    "parent_id": "mk7t2q9x4v1n",
    "external_key": "MKT101"
  }'
```

## Example response (201)

```json
{
  "object": "category",
  "id": "rz3p8w1d6c0b",
  "name": "MKT101 Marketing basics",
  "parent_id": "mk7t2q9x4v1n",
  "external_key": "MKT101",
  "children": []
}
```
