---
title: "Create Customer"
description: "Creates a new customer and assigns an organization-defined package via packageType."
---

`POST /api/customers`

## Authentication

This endpoint requires authentication.

```bash
BASE_URL="https://uptimeify.io"
TOKEN="wsm_<your-api-token>"
```

## Request Body

```json
{
  "name": "Customer Name",
  "email": "customer@deinkunde.com",
  "packageType": "business", // use the configured packageType or displayName for the organization
  "organizationId": 1, // optional (required only for global admins)
  "status": "active", // optional, Default: active
  "monthlyReportsEnabled": true, // optional, defaults to the package's monthlyReportsDefault
  "customFields": { ... } // optional
}
```

Notes:

- `packageType` can contain the configured package key or the package display name of the organization. Known aliases such as `aquisition_test` are normalized automatically.
- `monthlyReportsEnabled` is optional. Omit it and the new customer is seeded from the assigned package's `monthlyReportsDefault` (see [Upsert Package Config](/api/organization/upsert-package-config)); if the organization has no config row for that package, it falls back to `true`. An explicit value in the request always wins, the customer field alone decides whether a report is sent.
- If no configured package matches, the request is rejected with `400 Bad Request`.
- For non-global-admin users, `organizationId` is derived from your session/token and must not be overridden.
- For global admins, `organizationId` must be provided explicitly.

## Ownership & permission overrides (optional)

These fields control the customer's [managed vs. self-service](/monitoring/managed-vs-self-service) permissions and channel-type policy. They are **organization-write gated**: only organization admins (or global admins) can set them. A non-admin caller's values are ignored and the schema defaults apply.

`null` (or omitting the field) means *inherit from the customer's package config*.

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `allowSelfService` | boolean\|null | null (inherit) | Whether the customer may create and manage `self_service` monitors |
| `maxSelfServiceUrls` | number\|null | null (inherit) | Cap on the customer's **total** `self_service` monitors across all monitor types |
| `canEditManaged` | boolean | false | Exception: lets this customer edit `managed` monitors (class flips stay org-only). Grants are written to the audit log. |
| `enableEmailAlerts` | boolean\|null | null (inherit) | Channel-type policy override: email alerts |
| `enableSmsAlerts` | boolean\|null | null (inherit) | Channel-type policy override: SMS alerts |
| `enableWebhookAlerts` | boolean\|null | null (inherit) | Channel-type policy override: webhooks |
| `enableIntegrationAlerts` | boolean\|null | null (inherit) | Channel-type policy override: integrations |
| `enablePostRequestEscalation` | boolean\|null | null (inherit) | Channel-type policy override: POST-request escalation |

The legacy `notificationChannels` JSONB override is deprecated: channel-type policy lives in the `enable*` fields above.

## Response

```json
{
  "success": true,
  "customer": {
    "id": 64,
    "publicId": "6d74c32b-a97c-49b9-be3e-2b5e24bed826",
    "organizationId": 2,
    "name": "Example Customer",
    "email": "example@deinkunde.com",
    "notificationPhoneNumber": null,
    "notificationEmail": null,
    "packageId": 7,
    "packageType": "essential",
    "status": "active",
    "allowedCheckCountryCodes": null,
    "cancellationDate": null,
    "cancelledAt": null,
    "customFields": {
      "region": "EU",
      "planOwner": "Operations"
    },
    "monthlyReportsEnabled": true,
    "notificationChannels": null,
    "notificationTargets": null,
    "notificationRules": null,
    "smsUsageCurrentMonth": 0,
    "createdAt": "2026-04-04T12:27:13.415Z",
    "updatedAt": "2026-04-04T12:27:13.415Z"
  }
}
```

