# Create a district heating contract

Use this workflow to create a district heating (`NO_DH`) contract for a customer in Norway.

A Contract connects a Customer, one or more Products, and a Metering Point. In the UtilityCloud API, Metering Points are referred to as `accountingPoint` or `AccountingPoint` in paths and request bodies. These terms refer to the same concept.

For `NO_DH`, Metering Points must exist in UtilityCloud before a contract can be created. They are registered through the Market Workflow Engine (MWE) and cannot be created as part of the contract flow. If a Metering Point is not yet registered, it must be added to MWE first.

## Endpoints

```http
POST /v1/cm/customers/search
POST /mwe/v2/QueryAccountingPointDetails
POST /mwe/v2/CreateAccountingPoint
POST /v1/cm/contracts
```

## When to use

Use this workflow when an external system needs to create a new district heating contract for a customer in Norway.

## Before you start

Make sure you have:

- the Metering Point identification for the customer's premises, provided by the district heating operator
- a product configured for the `NO_DH` service type in your UtilityCloud environment

:::note
`NO_DH` does not require a national identity number or a digital signature. These steps are not part of this workflow.
:::





## Step 1: Find or create the customer

If the customer already exists in UtilityCloud, search for them to retrieve their customer ID:

```http
POST /v1/cm/customers/search
```

```json
{
  "Customers": [
    "01019912345"
  ]
}
```

The identification value is the national identity number (SSN) for private customers. If the customer is found, the response returns the customer's `Guid`. Store this for use in Step 4.

If the customer does not exist, a new customer is created automatically as part of the contract creation in Step 4. In that case, include the customer details in the contract request body using the `Customer` object:

```json
{
  "Customer": {
    "GivenName": "Kari",
    "FamilyName": "Nordmann",
    "Identification": "01019912345",
    "CountryCode": "NO"
  }
}
```

For district heating customers where the SSN is not available, `BirthDate` can be used instead of `Identification`:

```json
{
  "Customer": {
    "GivenName": "Kari",
    "FamilyName": "Nordmann",
    "BirthDate": "01.01.1999",
    "CountryCode": "NO"
  }
}
```

`BirthDate` must be formatted as `DD.MM.YYYY`.


## Step 2: Find or register the Metering Point

Before creating a contract, the Metering Point must exist in UtilityCloud. Start by checking whether it is already registered.

### Search for an existing Metering Point

Search by identification in MWE to check whether the Metering Point is already registered:

```http
POST /mwe/v2/QueryAccountingPointDetails
```

```json
{
  "Header": {
    "EventID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  },
  "Payload": {
    "ServiceType": "NO_DH",
    "AccountingPoint": "700062000000123456"
  }
}
```

If the Metering Point is found, the response includes its details. Store the identification for use in Step 4, and skip to Step 3.

### Register the Metering Point if it does not exist

If the search returns no result, register the Metering Point in MWE using the create endpoint:

```http
POST /mwe/v2/CreateAccountingPoint
```

`EventID` is a value you generate. Use a new UUID for each request. It is used for tracing the operation.

```json
{
  "Header": {
    "EventID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  },
  "Payload": {
    "AccountingPointID": "700062000000123456",
    "ServiceType": "NO_DH",
    "GridOwnerData": {
      "MGACode": "50YC9N3IBEIX7JFB"
    },
    "ApAddress": {
      "StreetName": "Storgata",
      "BuildingNumber": "1",
      "PostCode": "7010",
      "CityName": "TRONDHEIM",
      "CountryCode": "NO"
    },
    "TaxationProfile": {
      "VATCode": "S",
      "ConsumptionCode": "XX",
      "NACE_DivisionCode": "100"
    },
    "AnnualPeriodEstimatedMetrics": {
      "Total": 15000
    }
  }
}
```

### Required fields for NO_DH

| Field | Description |
|---|---|
| `Header.EventID` | A UUID you generate. Used for tracing the request |
| `Payload.AccountingPointID` | Unique identification for the Metering Point, provided by the district heating operator |
| `Payload.ServiceType` | Must be `NO_DH` |
| `Payload.GridOwnerData.MGACode` | Metering grid area (MGA) code. See allowed values below |
| `Payload.ApAddress.StreetName` | Street name of the Metering Point address |
| `Payload.ApAddress.BuildingNumber` | Building number of the Metering Point address |
| `Payload.ApAddress.PostCode` | Post code of the Metering Point address |
| `Payload.ApAddress.CityName` | City name of the Metering Point address |
| `Payload.ApAddress.CountryCode` | Country code. Use `NO` for Norway |
| `Payload.TaxationProfile.VATCode` | VAT treatment. Use `S` for standard rate or `E` for exempt |
| `Payload.TaxationProfile.ConsumptionCode` | Consumption code for the Metering Point |
| `Payload.TaxationProfile.NACE_DivisionCode` | NACE industry division code |
| `Payload.AnnualPeriodEstimatedMetrics.Total` | Annual estimated consumption in kWh |

> `Payload.GridOwnerData.PriceAreaName` does not need to be provided. The price area is derived from the MGA code.

#### Allowed MGA codes for NO_DH

| MGA Code | MGA Name | Price Area |
|---|---|---|
| `50YDALCBGQAA6XBR` | KEA1 | NO1 |
| `50Y0PZ1-8GH-06KI` | NLANDSN1 | NO4 |
| `50Y2UI3GR1N0QUER` | NLANDSN2 | NO4 |
| `50Y98QGPCG0GQL0T` | NEAS1 | NO3 |
| `50YC9N3IBEIX7JFB` | FOSEN1 | NO3 |
| `50YK95649Y18F01O` | BKKN1 | NO5 |
| `50YK05ZHDDCGA4AK` | SUNNFJD1 | NO3 |

If the MGA code you need is not listed here, contact UtilityCloud to have it added.

:::tip
To update the details of an existing Metering Point, use `PUT /mwe/v2/UpdateAccountingPoint` instead.
:::

## Step 3: Select a product

Retrieve the available products for the `NO_DH` service type:

```http
GET /v1/cm/products?serviceTypeKey=NO_DH
```

Select the product that matches the commercial terms for this customer and note its `Id`.

## Step 4: Create the contract

Create the contract using `POST /v1/cm/contracts`. Include the customer ID from Step 1, the Metering Point identification from Step 2, and the product from Step 3.

If the customer already exists, reference them by `Guid`:

```http
POST /v1/cm/contracts
```

```json
{
  "RequestId": "a7b8c9d0-0000-0000-0000-000000000001",
  "StartDate": "2025-09-01T00:00:00Z",
  "Customer": {
    "Guid": "customer-guid-here"
  },
  "Account": {
    "Communication": [
      { "Channel": "Email", "Value": "kari.nordmann@example.com" },
      { "Channel": "Mobile", "Value": "+4799999999" }
    ]
  },
  "AccountingPoint": {
    "Identification": "700062000000123456"
  },
  "Products": [
    {
      "ProductId": "product-guid-here",
      "PrimaryProduct": true
    }
  ]
}
```

If the customer does not yet exist, include the full `Customer` object instead:

```json
{
  "RequestId": "a7b8c9d0-0000-0000-0000-000000000001",
  "StartDate": "2025-09-01T00:00:00Z",
  "Customer": {
    "GivenName": "Kari",
    "FamilyName": "Nordmann",
    "Identification": "01019912345",
    "CountryCode": "NO"
  },
  "Account": {
    "Communication": [
      { "Channel": "Email", "Value": "kari.nordmann@example.com" },
      { "Channel": "Mobile", "Value": "+4799999999" }
    ]
  },
  "AccountingPoint": {
    "Identification": "700062000000123456"
  },
  "Products": [
    {
      "ProductId": "product-guid-here",
      "PrimaryProduct": true
    }
  ]
}
```

## Response

A valid request returns:

```http
202 Accepted
```

The contract is processed asynchronously. Use the `RequestId` to trace the operation.

A newly created `NO_DH` contract progresses through the following statuses:

| Status | Description |
|---|---|
| `Pending` | Contract received and being processed |
| `Active` | Contract is active and in effect |
| `Rejected` | Contract was rejected. Check `RejectionCode` for the reason |


## Notes

Use a new `RequestId` for each request. The request ID is used for tracing and duplicate request handling.

`RequestId`, `eventID`, and `correlationID` are values you generate as the integrating developer. Use a new UUID for each request. These values are used to trace requests across systems and should be stored if you need to follow up on a specific operation.

`StartDate` must be midnight local time represented as an ISO 8601 date-time value.

In API paths and request bodies, Metering Points are referred to as `accountingPoint` or `AccountingPoint`. These terms refer to the same concept.

The Metering Point can be referenced in the contract request by `Identification` or by internal `Guid`. Using `Identification` is the most common approach when integrating from external systems.

## Related endpoints

```http
POST /v1/cm/customers/search
POST /mwe/v2/QueryAccountingPointDetails
POST /mwe/v2/CreateAccountingPoint
PUT /mwe/v2/UpdateAccountingPoint
POST /v1/cm/contracts
```
