# Configuration Resources

Configuration resources provide the IDs, codes, and metadata used by element, task, and publication
write payloads.

Use this page for v2 behavior. Use the [API reference](/api) for exact paths, schemas,
examples, response status codes, and endpoint-specific validation.

## Resource Families

| Family | Public v2 surface |
|--------|-------------------|
| Groups | `/api/v2/groups` |
| Platforms | `/api/v2/platforms` |
| Categories | `/api/v2/platforms/{platformId}/categories` for list/create, `/api/v2/categories/{id}` for item operations |
| Types | `/api/v2/platforms/{platformId}/types` for list/create, `/api/v2/types/{id}` for item operations |
| Element statuses | `/api/v2/element-statuses` |
| Publication statuses | `/api/v2/publication-statuses` and `/api/v2/publication-statuses/platform/{platformId}` |
| Task statuses | `/api/v2/task-statuses` |
| Task formats | `/api/v2/task-formats` |

Statuses and task formats are read-only through the public API.

## Lists And Lookups

Group, platform, status, task-format, category, and type lists use the shared v2 list response
shape:

```json
{
  "content": [],
  "size": 20,
  "hasMore": false
}
```

Use [Querying Lists](/docs/guides/api-conventions/querying-lists) for shared query behavior.

External-ID lookups use `/external-id/{externalId}` where exposed:

```text
GET /api/v2/groups/external-id/{externalId}
GET /api/v2/platforms/external-id/{externalId}
GET /api/v2/categories/external-id/{externalId}
GET /api/v2/types/external-id/{externalId}
```

External IDs are integration identifiers, not uniqueness guarantees. Persist the returned v2 `id`
for later writes whenever possible.

## Write Models

:::caution{title="Map responses through the request schema"}

Configuration write payloads contain writable state only. Do not send a response body back as a
write request without mapping it through the operation's request schema.

:::

| Resource | Create | Replace | Patch |
|----------|--------|---------|-------|
| Group | `name`, optional `externalId`, optional `parentGroupId` | `name`, optional `externalId` | presence-aware `name` and `externalId` |
| Platform | `name` plus platform fields and optional schedule fields | full replacement, including required platform fields | presence-aware patch; schedule fields follow platform schedule rules |
| Category | platform ID in path, `name`, optional `externalId`, optional `parentCategoryId` | `name`, optional `externalId`, required `parentCategoryId` field that can be `null` | presence-aware `name`, `externalId`, and `parentCategoryId` |
| Type | platform ID in path, `name`, optional `externalId` | `name`, optional `externalId` | presence-aware `name` and `externalId` |

Create operations for groups, platforms, platform-scoped categories, and platform-scoped types return
`201 Created`.

## Category And Type Placement

Categories and types belong to a publication platform.

For categories:

- list and create categories through `/api/v2/platforms/{platformId}/categories`.
- use `parentCategoryId` to create or move a subcategory.
- `parentCategoryId: null` means top-level placement where the operation documents it.
- existing top-level categories cannot be moved under another parent through `PUT` or `PATCH`; send
  `parentCategoryId: null` on `PUT`, or omit it on `PATCH`.
- only top-level categories can be used as parents.

For types:

- list and create types through `/api/v2/platforms/{platformId}/types`.
- update a persisted type through `/api/v2/types/{id}`.
- update and patch payloads do not move a type to another platform.

## Delete Behavior

Configuration deletes have two success outcomes:

| Resource | Immediate response | Deferred response | Notes |
|----------|--------------------|-------------------|-------|
| Group | `204 No Content` | `202 Accepted` with a message body | Deleting a group with subgroups can fail with `400 Bad Request`; delete child groups first. |
| Platform | `204 No Content` | `202 Accepted` with a message body | Only platforms created through the API can be deleted through the API; platforms created in the Kordiam app return `400 Bad Request`. This is not exposed in the platform response, so handle it at delete time. |
| Category | `204 No Content` | `202 Accepted` with a message body | Category delete can remove linked publications according to category-delete business rules. |
| Type | `204 No Content` | Not exposed | Deletes the addressed type. |

Either status can be returned for the same resource, depending on how much related data the
deletion has to process. Branch on the status code at runtime: `204` means the deletion is already
complete, while `202` means it was accepted and finishes asynchronously — re-read the resource (or
its parent) before assuming it is gone.

## Statuses And Task Formats

Status families are separate:

- element statuses apply to the root story/event workflow.
- publication statuses apply to publications; platform-scoped status reads include
  `triggersExport` (whether reaching that status exports the content to the platform's connected
  external system).
- task statuses apply to tasks and are used through task formats.

A **task format** is the kind of deliverable a task produces (text, picture, video, and so on). Task
formats expose:

- `typeCode` for the format kind: `1` text, `2` picture, `3` video, `4` audio, `5` other.
- `active`.
- `defaultTaskStatus`.
- `taskStatuses`.
- `textLength` only for text formats.

Use IDs from these endpoints when building element, task, or publication write payloads.

## Related Guides

- [Platform Schedule Configuration](/docs/guides/resource-guides/platform-schedule-configuration)
- [Write Semantics](/docs/guides/api-conventions/write-semantics)
- [Resource Model](/docs/getting-started/data-model)
- [Configuration Resource Migration](/docs/migration-from-v1/configuration-resources)
