---
title: "Create or update a company"
url: https://docs.gleap.ai/en/reference/rest-api/put-companies-companyid
method: PUT
path: "/companies/{companyId}"
api: "API Reference"
tag: "Company"
operationId: "Update"
updatedAt: "2026-11-01T18:40:15.677Z"
language: en
---

# Create or update a company

`PUT https://api.gleap.io/v3/companies/{companyId}`

Create or update a company by its external `companyId` (upsert). Only `name`, `plan`, `domain`, `value`, `sla`, `tags`, `address`, `customData` and the account owner (`owner` or `ownerEmail`) are accepted; any other field is ignored. `tags` REPLACES the stored list (an empty array clears it), while `address` and `customData` are merged into the existing values rather than replaced. `customData` accepts up to 100 primitive values, `tags` up to 50. Setting a non-empty `name` here marks it authoritative, so names sent by the SDK will no longer overwrite it. `owner` is the id of a user in this project (`ownerEmail` their email address); `null` or `""` clears it. An owner that is not a project member's id or email is ignored (the rest of the update still applies), so check `owner` in the response.

## Authorization

- `Authorization` (header, required): `Bearer <token>`

## Path parameters

- `companyId` (string, required)

## Headers

- `project` (string, required)

## Request body (`application/json`, required)

- `name` (any): Text. Display name. A non-empty name set here is never overwritten by names the SDK sends.
- `plan` (any): Text.
- `domain` (any): Text, e.g. "example.com".
- `value` (any): Number (numeric strings are accepted). Account value, e.g. yearly revenue.
- `sla` (any): Number of seconds (numeric strings are accepted). Response-time SLA.
- `tags` (any): List of texts. Replaces the stored tags (an empty list clears them). Up to 50.
- `address` (any): Object with line1, line2, city, state, postalCode, country (texts). Merged into the stored address.
- `customData` (any): Object of texts, numbers, booleans or lists. Merged into the stored custom data. Up to 100 keys.
- `owner` (any): Text. Id of the user in this project who owns the account; null or "" clears it.
- `ownerEmail` (any): Text. Email of that user, instead of `owner`; null or "" clears it.

## Example request

```bash
curl --request PUT \
  --url 'https://api.gleap.io/v3/companies/{companyId}' \
  --header 'Authorization: Bearer <token>' \
  --header 'project: <project>' \
  --header 'Content-Type: application/json' \
  --data '{
  "name": "Bäckerei Huber GmbH",
  "plan": "Kplus Premium",
  "domain": "baeckerei-huber.at",
  "value": 4800,
  "tags": [
    "vip"
  ],
  "address": {
    "city": "Innsbruck",
    "country": "AT"
  },
  "customData": {
    "licenseNumber": "LIZ-10442",
    "modules": [
      "Kassa",
      "DMS"
    ]
  },
  "ownerEmail": "support@example.com"
}'
```

## Responses

### 200 (`application/json`)

Ok

- `_id` (string, required)
- `companyId` (string, required)
- `name` (string)
- `plan` (string)
- `domain` (string)
- `value` (number<double>)
- `sla` (number<double>)
- `tags` (string[])
- `address` (object): Request and response shapes of the companies API. They exist for the OpenAPI spec (the docs playground renders a body form from it); the service still whitelists and coerces every field itself (normalizeCompanyPayload).
  - `line1` (string)
  - `line2` (string)
  - `city` (string)
  - `state` (string)
  - `postalCode` (string)
  - `country` (string)
- `customData` (object)
- `owner` (string)
- `ownerEmail` (string)
- `nameIsAuthoritative` (boolean)
- `lastSeenAt` (string)
- `createdAt` (string)
- `updatedAt` (string)

```json
{
  "_id": "string",
  "companyId": "string",
  "name": "string",
  "plan": "string",
  "domain": "string",
  "value": 0,
  "sla": 0,
  "tags": [
    "string"
  ],
  "address": {
    "line1": "string",
    "line2": "string",
    "city": "string",
    "state": "string",
    "postalCode": "string",
    "country": "string"
  },
  "customData": {},
  "owner": "string",
  "ownerEmail": "string",
  "nameIsAuthoritative": true,
  "lastSeenAt": "string",
  "createdAt": "string",
  "updatedAt": "string"
}
```
