# Bulk create components

Create multiple components in a single request.

Source: https://statusdashboard.com/docs/api/status-dashboards/components/bulk-create

`POST /app/components/bulk`

Creates up to 500 components in a single request. Requires the **admin** role.

Each row in the request is independently classified — the endpoint never fails wholesale. Rows that would exceed the quota, duplicate an existing name, or fail validation are reported in the response rather than causing the entire request to fail.

***

## Request
See [API Basics](/docs/api) for required headers.

### Request body
| Field                      | Type   | Required | Description                                                         |
| -------------------------- | ------ | -------- | ------------------------------------------------------------------- |
| `components`               | array  | Yes      | Array of component objects to create. Minimum 1, maximum 500 items. |
| `components[].name`        | string | Yes      | Display name for the component. Maximum 50 characters.              |
| `components[].description` | string | No       | Short description of the component. Maximum 150 characters.         |

***

## Sample request
```bash
curl -X POST https://api.statusdashboard.com/app/components/bulk \
  -H "Authorization: Bearer bcf847abf5c6:def456" \
  -H "Content-Type: application/json" \
  -d '{
    "components": [
      { "name": "API Gateway", "description": "REST API gateway" },
      { "name": "Payment Processing", "description": "Stripe payment service" },
      { "name": "Website" }
    ]
  }'
```

## Sample response
**Status: `200 OK`**

```json
{
  "created": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "name": "API Gateway",
      "description": "REST API gateway",
      "currentStatus": "Operational",
      "currentStatusSnapshot": {
        "label": "Operational",
        "color": "#10b981",
        "icon": "check-circle"
      },
      "statusUpdatedAt": "2026-06-13T10:00:00.000Z",
      "createdAt": "2026-06-13T10:00:00.000Z"
    },
    {
      "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
      "name": "Payment Processing",
      "description": "Stripe payment service",
      "currentStatus": "Operational",
      "currentStatusSnapshot": {
        "label": "Operational",
        "color": "#10b981",
        "icon": "check-circle"
      },
      "statusUpdatedAt": "2026-06-13T10:00:00.000Z",
      "createdAt": "2026-06-13T10:00:00.000Z"
    },
    {
      "id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
      "name": "Website",
      "description": "",
      "currentStatus": "Operational",
      "currentStatusSnapshot": {
        "label": "Operational",
        "color": "#10b981",
        "icon": "check-circle"
      },
      "statusUpdatedAt": "2026-06-13T10:00:00.000Z",
      "createdAt": "2026-06-13T10:00:00.000Z"
    }
  ],
  "skipped": [],
  "errors": [],
  "quotaExceeded": []
}
```

All new components start with a status of **Operational**.

***

## Response fields
| Field           | Type                 | Description                                                                                                             |
| --------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `created`       | Component\[]         | Components successfully created in this request. Each item includes `currentStatusSnapshot` (`label`, `color`, `icon`). |
| `skipped`       | `{ name, reason }[]` | Rows not created because a component with the same name already exists (case-insensitive).                              |
| `errors`        | `{ name, reason }[]` | Rows rejected due to a duplicate name within this import batch (second occurrence onwards).                             |
| `quotaExceeded` | `{ name }[]`         | Valid, unique rows that could not be created because the organization's component quota was exhausted.                  |

***

## Row classification logic
Each input row is processed as follows:

1. **Error** — the same name appears earlier in this batch (second occurrence onwards). Not written to the database.
2. **Create attempt** — all other rows are written transactionally (name sentinel + component + quota counter).
3. **Skip** — create attempt failed because the name already exists in the organization.
4. **Quota exceeded** — create attempt failed because the plan component quota was reached; remaining unprocessed rows are also reported here.

The first occurrence of a name in the batch always wins for create attempts.

***

## Error responses
| Status | When                                                                                                                                                                                                              |
| ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400`  | Validation failure — `components` is missing, empty, exceeds 500 items, malformed JSON, the request body is not a JSON object, or a row fails field-level validation (name too long, description too long, etc.). |
| `403`  | Insufficient permissions.                                                                                                                                                                                         |
