> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.lettbestilt.no/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.lettbestilt.no/_mcp/server.

# Change the restaurant's settings

PATCH https://www.lettbestilt.no/api/v1/partner/restaurants/{slug}/settings
Content-Type: application/json

**Partner key + restaurant key.** Changes the fields you send; a field you leave out stays as it is. Same rules as the restaurant dashboard. With `expectedVersion`, nothing is written if the settings changed since you read them (`409 CHANGED`); an order does not count as a change.

The legal fields (`orgNumber`, `legalName`, `addressLine1`, `postalCode`, `city`) can be changed until the owner has signed the customer agreement; after that a new value gives `409 LEGAL_LOCKED` (the stored value is accepted). The logo and cover image must be uploaded to LettBestilt. Remove `version`, `updatedAt` and `legal` before you send a `GET` response back. Slug, email, the ordering page, the font, invoicing, agreements, payment and printers cannot be changed here. Not allowed for an archived restaurant. Every change is logged with the field names, never the values.

Reference: https://docs.lettbestilt.no/api-reference/partner/update-partner-restaurant-settings

## Authentication

- `Authorization` header (bearer token, required) — The partner key (`lbp_test_…` or `lbp_live_…`), sent as `Authorization: Bearer lbp_…` and created in LettBestilt Partner under **Partner key**. It belongs to the whole partner, not to a restaurant, and only works against `/api/v1/partner`. Server to server only: a request with an `Origin` header is rejected with `403 FORBIDDEN`, and the key must never be in a browser. A TEST key sees and creates only sandboxes; LIVE keys work once LettBestilt Partner is open. A suspended or archived partner, a revoked key and a restaurant key (`lbs_…`) here give `401 UNAUTHORIZED`; an expired key gives `401 KEY_EXPIRED`.
- `X-LettBestilt-Restaurant-Key` header (required) — The restaurant's own key (`lbs_test_…` or `lbs_live_…`) for calls about one restaurant in the partner API, sent together with the partner key. The key must have full access (scope `*`, otherwise `403 INSUFFICIENT_SCOPE`), belong to a restaurant the partner owns and be in the same environment as the partner key. A restaurant that does not exist, belongs to another partner or does not match the key always gives the same `404 RESTAURANT_NOT_FOUND`. Older keys without an environment in the prefix (`lbs_<random>`) are not accepted here; rotate them in LettBestilt Partner.

## Request

### Path parameters

- `slug` (string, required) — The restaurant's slug. It must match the restaurant key in `X-LettBestilt-Restaurant-Key`.

### Body (application/json)

This endpoint expects a PartnerSettingsPatch.

- `name` (string, optional) — The restaurant's name as guests see it.
- `description` (string, optional, nullable)
- `cuisineType` (string, optional, nullable) — Cuisine, e.g. "Pizza".
- `phone` (string, optional, nullable)
- `website` (string, optional, nullable) — The restaurant's website (http/https).
- `publicAddressLine1` (string, optional, nullable) — The visiting address. Empty = use the legal address (all or nothing).
- `publicPostalCode` (string, optional, nullable) — 4 digits. An empty string or null clears it.
- `publicCity` (string, optional, nullable)
- `latitude` (double, optional, nullable) — Sent together with `longitude`: both or neither.
- `longitude` (double, optional, nullable) — Sent together with `latitude`: both or neither.
- `primaryColor` (string, optional)
- `secondaryColor` (string, optional)
- `logoUrl` (string, optional, nullable) — Logo. Only a file uploaded to LettBestilt's own UploadThing app (https\://\<appId>.ufs.sh/f/… or [https://utfs.io/a/\&lt;appId\&gt;/…](https://utfs.io/a/\&lt;appId\&gt;/…)); other addresses give 422. The stored value is accepted (including older links). An empty string or null removes the image.
- `coverImageUrl` (string, optional, nullable) — Cover image. Only a file uploaded to LettBestilt's own UploadThing app (https\://\<appId>.ufs.sh/f/… or [https://utfs.io/a/\&lt;appId\&gt;/…](https://utfs.io/a/\&lt;appId\&gt;/…)); other addresses give 422. The stored value is accepted (including older links). An empty string or null removes the image.
- `pickupEnabled` (boolean, optional) — At least one of `pickupEnabled` and `deliveryEnabled` must be true.
- `deliveryEnabled` (boolean, optional) — At least one of `pickupEnabled` and `deliveryEnabled` must be true. Delivery zones are set separately.
- `defaultPrepMinutes` (integer, optional) — Base preparation time for pickup, in minutes (without rush).
- `defaultDeliveryMinutes` (integer, optional) — Base delivery time, in minutes (without rush).
- `trackingHeaderText` (string, optional, nullable) — Heading on the tracking page.
- `trackingPickupInstructions` (string, optional, nullable)
- `trackingDeliveryInstructions` (string, optional, nullable)
- `trackingShowEta` (boolean, optional)
- `trackingShowMap` (boolean, optional)
- `receiptHeaderText` (string, optional, nullable)
- `receiptFooterText` (string, optional, nullable)
- `googleReviewUrl` (string, optional, nullable) — Link to Google reviews on the receipt, https only. An empty string or null clears it.
- `orgNumber` (string, optional, nullable) — Legal. 9 digits with a valid check digit (mod11); spaces are tolerated and removed. Locked when the owner has signed the customer agreement.
- `legalName` (string, optional, nullable) — Legal. Locked when the owner has signed the customer agreement.
- `addressLine1` (string, optional, nullable) — Legal address (used for the customer agreement and the payment provider). Locked when the owner has signed the customer agreement.
- `postalCode` (string, optional, nullable) — Legal. 4 digits. Locked when the owner has signed the customer agreement.
- `city` (string, optional, nullable) — Legal. Locked when the owner has signed the customer agreement.
- `expectedVersion` (string, optional) — `version` from GET. If the settings have changed since, `409 CHANGED` and nothing is written. An order does not change the version.

## Response

### 200

The settings after the change.

- `data` (PartnerSettings, required)

## Errors

### 400 Bad Request Error

`INVALID_JSON`: the body is not valid JSON.

- `error` (ErrorBody, required)

### 401 Unauthorized Error

`UNAUTHORIZED`: a key is missing, invalid or revoked, the two keys are from different environments (TEST and LIVE), or the partner is suspended or archived. `KEY_EXPIRED`: a key is past its expiry date.

- `error` (ErrorBody, required)

### 403 Forbidden Error

`FORBIDDEN`: the request has an `Origin` header (server to server only). `PARTNER_AGREEMENT_REQUIRED`: a LIVE key, but the partner agreements are not signed. `PARTNER_NOT_APPROVED`: LettBestilt has not approved the partner yet (all keys). `INSUFFICIENT_SCOPE`: the restaurant key does not have full access (`error.details.requiredScope` is `"*"`).

- `error` (ErrorBody, required)

### 404 Not Found Error

`RESTAURANT_NOT_FOUND`: the same response whether the slug does not exist, belongs to another partner or does not match the restaurant key.

- `error` (ErrorBody, required)

### 409 Conflict Error

`CHANGED`: the settings changed since `expectedVersion`, or at the same time. `LEGAL_LOCKED`: the owner has signed the customer agreement; `error.details.fields` lists the legal fields that would have got a new value. `DEMO_RESTAURANT`: the demo restaurant cannot be changed through the API. `RESTAURANT_ARCHIVED`: the restaurant is archived.

- `error` (ErrorBody, required)

### 422 Unprocessable Entity Error

`VALIDATION_FAILED` with `error.details.issues` (a path per field): an invalid value, an unknown field or one that cannot be changed through the API (e.g. `slug`, `email`, `storefrontEnabled`), an empty body, only one of `latitude`/`longitude`, a logo or cover image from another host, an invalid organisation number, a `googleReviewUrl` without https, an invalid `expectedVersion`, `version`/`updatedAt`/`legal` sent back from GET, or both `pickupEnabled` and `deliveryEnabled` ending up false.

- `error` (ErrorBody, required)

### 429 Too Many Requests Error

`RATE_LIMITED`: more than 120 calls per minute for this partner key, or more than 600 per minute for the partner across all its keys (reads and writes). Writes also share a bucket of 30 changes per minute per partner and environment. See `Retry-After`.

- `error` (ErrorBody, required)

## Types

### PartnerSettings

- `name` (string, required) — The restaurant's name as guests see it.
- `description` (string, required, nullable)
- `cuisineType` (string, required, nullable) — Cuisine, e.g. "Pizza".
- `phone` (string, required, nullable)
- `website` (string, required, nullable) — The restaurant's website (http/https).
- `publicAddressLine1` (string, required, nullable) — The visiting address. Empty = use the legal address (all or nothing).
- `publicPostalCode` (string, required, nullable) — 4 digits. An empty string or null clears it.
- `publicCity` (string, required, nullable)
- `latitude` (double, required, nullable) — Sent together with `longitude`: both or neither.
- `longitude` (double, required, nullable) — Sent together with `latitude`: both or neither.
- `primaryColor` (string, required)
- `secondaryColor` (string, required)
- `logoUrl` (string, required, nullable) — Logo. Only a file uploaded to LettBestilt's own UploadThing app (https\://\<appId>.ufs.sh/f/… or [https://utfs.io/a/\&lt;appId\&gt;/…](https://utfs.io/a/\&lt;appId\&gt;/…)); other addresses give 422. The stored value is accepted (including older links). An empty string or null removes the image.
- `coverImageUrl` (string, required, nullable) — Cover image. Only a file uploaded to LettBestilt's own UploadThing app (https\://\<appId>.ufs.sh/f/… or [https://utfs.io/a/\&lt;appId\&gt;/…](https://utfs.io/a/\&lt;appId\&gt;/…)); other addresses give 422. The stored value is accepted (including older links). An empty string or null removes the image.
- `pickupEnabled` (boolean, required) — At least one of `pickupEnabled` and `deliveryEnabled` must be true.
- `deliveryEnabled` (boolean, required) — At least one of `pickupEnabled` and `deliveryEnabled` must be true. Delivery zones are set separately.
- `defaultPrepMinutes` (integer, required) — Base preparation time for pickup, in minutes (without rush).
- `defaultDeliveryMinutes` (integer, required) — Base delivery time, in minutes (without rush).
- `trackingHeaderText` (string, required, nullable) — Heading on the tracking page.
- `trackingPickupInstructions` (string, required, nullable)
- `trackingDeliveryInstructions` (string, required, nullable)
- `trackingShowEta` (boolean, required)
- `trackingShowMap` (boolean, required)
- `receiptHeaderText` (string, required, nullable)
- `receiptFooterText` (string, required, nullable)
- `googleReviewUrl` (string, required, nullable) — Link to Google reviews on the receipt, https only. An empty string or null clears it.
- `orgNumber` (string, required, nullable) — Legal. 9 digits with a valid check digit (mod11); spaces are tolerated and removed. Locked when the owner has signed the customer agreement.
- `legalName` (string, required, nullable) — Legal. Locked when the owner has signed the customer agreement.
- `addressLine1` (string, required, nullable) — Legal address (used for the customer agreement and the payment provider). Locked when the owner has signed the customer agreement.
- `postalCode` (string, required, nullable) — Legal. 4 digits. Locked when the owner has signed the customer agreement.
- `city` (string, required, nullable) — Legal. Locked when the owner has signed the customer agreement.
- `version` (string, required) — Version of the settings above (changes only when one of these fields changes). Send it as `expectedVersion` in PATCH to avoid overwriting a concurrent change. Do not send it as a field.
- `updatedAt` (datetime, required) — When anything on the restaurant last changed, including orders. For information only: use `version` for concurrency. Do not send it back in PATCH.
- `legal` (PartnerSettingsLegal, required)
- `textCleaned` (integer, optional) — Only in the response to a write, and only when something was cleaned: the number of text fields where links, email addresses, HTML, `javascript:` or invisible direction marks were removed (as for the menu).

### ErrorBody

- `code` (enum, required) — A machine-readable error code.
  - Allowed values: `MISSING_SLUG`, `MISSING_TOKEN`, `INVALID_JSON`, `INVALID_SUCCESS_URL`, `INVALID_CANCEL_URL`, `VALIDATION_FAILED`, `RESTAURANT_NOT_FOUND`, `ORDER_NOT_FOUND`, `RATE_LIMITED`, `BAD_REQUEST`, `UNAUTHORIZED`, `FORBIDDEN`, `INSUFFICIENT_SCOPE`, `KEY_EXPIRED`, `POPUP_NOT_AVAILABLE`, `PRICE_CHANGED`, `PAYMENT_INCOMPLETE`, `PAYMENT_PENDING`, `PAYMENT_PROVIDER_INVALID`, `FULFILLMENT_NOT_ALLOWED`, `IDEMPOTENCY_CONFLICT`, `DINE_IN_DISABLED`, `PARTY_TOO_LARGE`, `TOO_EARLY`, `NO_TABLE`, `INVALID_PARTY_SIZE`, `INTERNAL_ERROR`, `PARTNER_AGREEMENT_REQUIRED`, `IDEMPOTENCY_KEY_REQUIRED`, `SLUG_TAKEN`, `SANDBOX_LIMIT`, `RETENTION`, `RESTAURANT_ARCHIVED`, `KEY_NOT_FOUND`, `KEY_IN_USE`, `WEBHOOK_NOT_FOUND`, `WEBHOOK_LIMIT`, `CHANGED`, `PDF_TOO_LARGE`, `PDF_INVALID`, `PDF_PASSWORD`, `PDF_TOO_MANY_PAGES`, `PDF_NO_TEXT`, `PDF_PARSE_TIMEOUT`, `MENU_IMPORT_EMPTY`, `FILE_UNSUPPORTED`, `IMAGE_HEIC`, `IMAGE_INVALID`, `IMAGE_DIMENSIONS`, `MENU_IMPORT_UNAVAILABLE`, `MENU_IMPORT_AI_LIMIT`, `MENU_IMPORT_TOO_BIG`, `MENU_IMPORT_NOT_FOUND`, `MENU_IMPORT_CLOSED`, `PARTNER_NOT_APPROVED`, `PARTNER_DATA_LOCKED`, `DOMAIN_NOT_FOUND`, `DOMAIN_TAKEN`, `DOMAIN_LIMIT`, `DOMAIN_MANAGED`, `DOMAIN_NOT_VERIFIED`, `OWNER_EXISTS`, `OWNER_EMAIL_NOT_ALLOWED`, `OWNER_INVITE_NOT_FOUND`, `SANDBOX_NOT_SUPPORTED`, `INVITE_SEND_FAILED`, `GO_LIVE_NOT_REQUIRED`, `GO_LIVE_NOT_READY`, `GO_LIVE_CHECKS_FAILED`, `GO_LIVE_ALREADY_REQUESTED`, `GO_LIVE_ALREADY_APPROVED`, `GO_LIVE_NOTHING_TO_WITHDRAW`, `DEMO_RESTAURANT`, `LEGAL_LOCKED`, `HOURS_OVERRIDE_NOT_FOUND`, `HOURS_OVERRIDE_LIMIT`, `DELIVERY_ZONE_NOT_FOUND`, `DELIVERY_ZONE_LIMIT`, `MENU_NOT_FOUND`, `MENU_IS_DEFAULT`, `CATEGORY_NOT_FOUND`, `PRODUCT_NOT_FOUND`, `ADDON_GROUP_NOT_FOUND`, `CATEGORY_NOT_EMPTY`, `CATEGORY_LIMIT`, `PRODUCT_LIMIT`, `ADDON_GROUP_LIMIT`, `KEY_ROLE_FORBIDDEN`, `WHITE_LABEL_REQUIRED`, `LOGO_NOT_ALLOWED`, `FILE_TOO_LARGE`, `UPLOAD_FAILED`, `PARTNER_ARCHIVED`, `PARTNER_NEWS_FORBIDDEN`, `NEWS_NOT_FOUND`, `NOT_DRAFT`, `NOT_PUBLISHED`, `NOT_SCHEDULED`, `NOT_CLAIMABLE`, `NO_RECIPIENTS`, `IMAGE_NOT_ALLOWED`, `SENDER_DOMAIN_ALREADY_SET`, `SENDER_DOMAIN_NOT_SET`, `DOMAIN_EXISTS`, `SENDER_DOMAIN_REJECTED`, `EMAIL_SERVICE_UNAVAILABLE`, `HUMAN_REQUIRED`, `LENGTH_REQUIRED`, `PAYLOAD_TOO_LARGE`
- `message` (string, required) — A human-readable explanation, often in Norwegian. For business rules it is usually suitable to show the customer.
- `requestId` (string, required) — The same value as the `X-Request-Id` response header. Search for it in the API log in LettBestilt Partner, and include it when you contact LettBestilt.
- `details` (any, optional) — Extra data for some codes, for example `issues` for `VALIDATION_FAILED`, the totals for `PRICE_CHANGED` or `requiredScope` for `INSUFFICIENT_SCOPE`.

### PartnerSettingsLegal

- `locked` (boolean, required) — `true` when the owner has signed the customer agreement: `orgNumber`, `legalName`, `addressLine1`, `postalCode` and `city` cannot be changed through the API.

## Examples

**Request**

```json
{
  "name": "Pizza Roma",
  "primaryColor": "#B3261E",
  "pickupEnabled": true,
  "deliveryEnabled": true,
  "expectedVersion": "3f9a1c0d7be24e51"
}
```

**Response**

```json
{
  "data": {
    "name": "string",
    "description": "string",
    "cuisineType": "string",
    "phone": "string",
    "website": "string",
    "publicAddressLine1": "string",
    "publicPostalCode": "string",
    "publicCity": "string",
    "latitude": 1.1,
    "longitude": 1.1,
    "primaryColor": "#E63946",
    "secondaryColor": "#E63946",
    "logoUrl": "string",
    "coverImageUrl": "string",
    "pickupEnabled": true,
    "deliveryEnabled": true,
    "defaultPrepMinutes": 1,
    "defaultDeliveryMinutes": 1,
    "trackingHeaderText": "string",
    "trackingPickupInstructions": "string",
    "trackingDeliveryInstructions": "string",
    "trackingShowEta": true,
    "trackingShowMap": true,
    "receiptHeaderText": "string",
    "receiptFooterText": "string",
    "googleReviewUrl": "string",
    "orgNumber": "string",
    "legalName": "string",
    "addressLine1": "string",
    "postalCode": "string",
    "city": "string",
    "version": "string",
    "updatedAt": "2024-01-15T09:30:00Z",
    "legal": {
      "locked": true
    },
    "textCleaned": 1
  }
}
```

**SDK Code**

```python Partner_updatePartnerRestaurantSettings_example
import requests

url = "https://www.lettbestilt.no/api/v1/partner/restaurants/slug/settings"

payload = {
    "name": "Pizza Roma",
    "primaryColor": "#B3261E",
    "pickupEnabled": True,
    "deliveryEnabled": True,
    "expectedVersion": "3f9a1c0d7be24e51"
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.patch(url, json=payload, headers=headers)

print(response.json())
```

```javascript Partner_updatePartnerRestaurantSettings_example
const url = 'https://www.lettbestilt.no/api/v1/partner/restaurants/slug/settings';
const options = {
  method: 'PATCH',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"name":"Pizza Roma","primaryColor":"#B3261E","pickupEnabled":true,"deliveryEnabled":true,"expectedVersion":"3f9a1c0d7be24e51"}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go Partner_updatePartnerRestaurantSettings_example
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://www.lettbestilt.no/api/v1/partner/restaurants/slug/settings"

	payload := strings.NewReader("{\n  \"name\": \"Pizza Roma\",\n  \"primaryColor\": \"#B3261E\",\n  \"pickupEnabled\": true,\n  \"deliveryEnabled\": true,\n  \"expectedVersion\": \"3f9a1c0d7be24e51\"\n}")

	req, _ := http.NewRequest("PATCH", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby Partner_updatePartnerRestaurantSettings_example
require 'uri'
require 'net/http'

url = URI("https://www.lettbestilt.no/api/v1/partner/restaurants/slug/settings")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"name\": \"Pizza Roma\",\n  \"primaryColor\": \"#B3261E\",\n  \"pickupEnabled\": true,\n  \"deliveryEnabled\": true,\n  \"expectedVersion\": \"3f9a1c0d7be24e51\"\n}"

response = http.request(request)
puts response.read_body
```

```java Partner_updatePartnerRestaurantSettings_example
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.patch("https://www.lettbestilt.no/api/v1/partner/restaurants/slug/settings")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"name\": \"Pizza Roma\",\n  \"primaryColor\": \"#B3261E\",\n  \"pickupEnabled\": true,\n  \"deliveryEnabled\": true,\n  \"expectedVersion\": \"3f9a1c0d7be24e51\"\n}")
  .asString();
```

```php Partner_updatePartnerRestaurantSettings_example
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PATCH', 'https://www.lettbestilt.no/api/v1/partner/restaurants/slug/settings', [
  'body' => '{
  "name": "Pizza Roma",
  "primaryColor": "#B3261E",
  "pickupEnabled": true,
  "deliveryEnabled": true,
  "expectedVersion": "3f9a1c0d7be24e51"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp Partner_updatePartnerRestaurantSettings_example
using RestSharp;

var client = new RestClient("https://www.lettbestilt.no/api/v1/partner/restaurants/slug/settings");
var request = new RestRequest(Method.PATCH);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"name\": \"Pizza Roma\",\n  \"primaryColor\": \"#B3261E\",\n  \"pickupEnabled\": true,\n  \"deliveryEnabled\": true,\n  \"expectedVersion\": \"3f9a1c0d7be24e51\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift Partner_updatePartnerRestaurantSettings_example
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "name": "Pizza Roma",
  "primaryColor": "#B3261E",
  "pickupEnabled": true,
  "deliveryEnabled": true,
  "expectedVersion": "3f9a1c0d7be24e51"
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://www.lettbestilt.no/api/v1/partner/restaurants/slug/settings")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PATCH"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```