# Get companies

> GET /v1/companies · Core resources API

Source: https://developer.kustomer.com/api/core-resources/get-companies

```http
GET https://{orgname}.api.kustomerapp.com/v1/companies
Authorization: Bearer <API key>
```

## Authorization

Requires any one of these roles: `org.permission.company.read`; or legacy `org.user.company.read`. The API key or user must hold at least one of them. Legacy roles predate permission sets and still work.

Retrieves all companies. You can optionally filter this list by the company name or the unique external company ID.

### Note
> If you use both the `externalId` and `filter` query params, the request ignores both query params.

## About Companies

A company is an organization that your customers belong to, such as a business account. It holds the organization's contact details, tags and custom attributes, can own custom objects, and can sit in a parent-child hierarchy with other companies.

Companies group customers who belong to the same organization, which matters most for B2B support: agents can see which account a person works for, and searches, workflows and reports can filter on company data. A customer links to one company through its `company` attribute, which holds the company ID. Companies are usually created by a CRM sync or an import, then kept up to date as the source system changes. There is no `DELETE` endpoint: you delete a company by updating it with `deleted: true`.

#### Key fields

`name` is the only required field. Set `externalId` to the account's ID in your own system so you can find it again: `GET /v1/companies` accepts `externalId`, or `filter` for a name match, but if you send both, both are ignored. The contact lists `emails`, `phones`, `whatsapps`, `socials`, `urls`, `domains` and `locations` each hold up to 10 entries, and `tags` holds up to 20. Your own fields go in `custom`, named with a type suffix such as `tierStr` or `seatsNum`; see [custom attributes](https://developer.kustomer.com/docs/concepts/custom-attributes).

Updates merge into the existing company by default. Add `replace=true` to replace the whole resource. Updates are subject to object rate limiting, which caps how often one user can change the same company; see [rate limits](https://developer.kustomer.com/docs/concepts/rate-limits).

#### Hierarchies

The hierarchy endpoints link existing companies into trees, such as a parent company and its subsidiaries. Each link is an edge of type `kedge` with its own ID: `sourceId` is the parent and `targetId` is the child. Edges belong to a named tree (`name`, default `company_hierarchy`), and a company has at most one parent per tree, so setting a new parent replaces the old edge. A tree can be at most 20 levels deep and hold at most 2,000 companies. Cycles and self-parenting fail with `400`.

Most hierarchy endpoints take a company ID. The exception is `DELETE /v1/kedge/{id}`, which takes an edge ID. Reading a company returns a `kedge-node` with its parent edge, one page of direct children, and `breadcrumbs` from the root down to the company itself.

#### Which endpoint to use

| To | Call |
| --- | --- |
| List companies, or find one by `externalId` or name | [`GET /v1/companies`](https://developer.kustomer.com/api/core-resources/get-companies) |
| Create, read or update a company (including deleting it with `deleted: true`) | [`POST /v1/companies`](https://developer.kustomer.com/api/core-resources/create-company), [`GET`](https://developer.kustomer.com/api/core-resources/get-company-by-id) or [`PUT /v1/companies/{id}`](https://developer.kustomer.com/api/core-resources/update-company-attributes) |
| List a company's custom objects of one Klass | [`GET /v1/companies/{id}/klasses/{name}`](https://developer.kustomer.com/api/core-resources/find-company-kobjects-custom-objects) |
| Create or update up to 100 companies at once | [`POST`](https://developer.kustomer.com/api/core-resources/bulk-create-companies) or [`PUT /v1/companies/bulk`](https://developer.kustomer.com/api/core-resources/bulk-batch-update-companies) |
| Link a child to a parent | [`POST /v1/kedge`](https://developer.kustomer.com/api/core-resources/create-a-company-hierarchy-edge) or [`POST /v1/kedge/{id}/parent`](https://developer.kustomer.com/api/core-resources/set-a-companys-parent) |
| Read a company's place in the tree | [`GET /v1/kedge/{id}`](https://developer.kustomer.com/api/core-resources/get-a-company-hierarchy-node), or [`GET /v1/kedge/{id}/parent`](https://developer.kustomer.com/api/core-resources/get-a-companys-direct-parent-edge) for just the parent edge (`404` for a root) |
| Make a company a root, keeping its children | [`DELETE /v1/kedge/{id}/parent`](https://developer.kustomer.com/api/core-resources/remove-a-companys-parent) |
| Delete one edge by its edge ID | [`DELETE /v1/kedge/{id}`](https://developer.kustomer.com/api/core-resources/delete-a-company-hierarchy-edge) |

Bulk requests run asynchronously and return a bulk operation; poll it with the [bulk operations](https://developer.kustomer.com/api/core-resources#bulk-operations) endpoints. Add `_clientRef` to every item to match per-item results back to your rows. Deleting a company that still has children in any tree fails with `409 Conflict`, naming the first blocking child and its tree; unlink or delete that child first. A `409` on an edge write means another write to the same tree was in progress, so retry it.

Related: [Customers](https://developer.kustomer.com/api/core-resources#customers), [Model company hierarchies](https://developer.kustomer.com/docs/guides/company-hierarchy), [Bulk operations](https://developer.kustomer.com/docs/guides/bulk-operations), [KObjects (custom objects)](https://developer.kustomer.com/api/core-resources#kobjects-custom-objects)

### Recipes

#### 1. Find or create a company by your account ID

Map an account in your CRM to one Kustomer company, so a sync can run again without creating duplicates.

**Step 1.** [`GET /v1/companies`](https://developer.kustomer.com/api/core-resources/get-companies.md). Look the company up by the account's ID, which you store in `externalId`. The response is a list: the company is the first item in `data`, and an empty list means it doesn't exist yet. Don't add `filter` to the same request, because sending both parameters makes the API ignore both.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/companies?externalId=$ACCOUNT_ID" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v1/companies --query externalId=$ACCOUNT_ID | jq -r '.data[0].id // empty'
```

**Step 2.** [`POST /v1/companies`](https://developer.kustomer.com/api/core-resources/create-company.md). If there's no match, create the company. `name` needs at least 3 characters. Lists such as `domains` (each `{ domain }`), `emails` and `phones` hold up to 10 entries, and custom attributes go under `custom` with a type suffix such as `tierStr`. Keep `data.id`; customers link to the company by that ID.

```bash title="cURL"
curl --request POST "https://api.kustomerapp.com/v1/companies" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data "{\"name\": \"$ACCOUNT_NAME\", \"externalId\": \"$ACCOUNT_ID\", \"domains\": [{\"domain\": \"acme.example\"}], \"custom\": {\"tierStr\": \"enterprise\"}}"
```

```bash title="kusty"
kusty api POST /v1/companies \
  --field name="$ACCOUNT_NAME" --field externalId=$ACCOUNT_ID \
  --field domains.0.domain=acme.example --field custom.tierStr=enterprise \
  | jq -r .data.id
```

**Step 3.** [`PUT /v1/companies/{id}`](https://developer.kustomer.com/api/core-resources/update-company-attributes.md). When the account changes later, update the company. Fields you leave out are kept unless you add `replace=true`. Skip the call when nothing changed: one company can only be updated so often in a short window (see [Rate limits](https://developer.kustomer.com/docs/concepts/rate-limits#object-limits)).

```bash title="cURL"
curl --request PUT "https://api.kustomerapp.com/v1/companies/$COMPANY_ID" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{"custom": {"tierStr": "strategic"}}'
```

```bash title="kusty"
kusty api PUT /v1/companies/$COMPANY_ID --field custom.tierStr=strategic
```

> For a first import of many accounts, use [`POST /v1/companies/bulk`](https://developer.kustomer.com/api/core-resources/bulk-create-companies) with `_clientRef` on each item, and poll the job as described in [Bulk operations](https://developer.kustomer.com/docs/guides/bulk-operations).

#### 2. Link a customer to their company

Attach a person to the account they work for, so agents see the company on the customer's profile and searches can filter by company.

**Step 1.** [`PUT /v1/customers/{id}`](https://developer.kustomer.com/api/core-resources/update-customer.md). Set the customer's `company` to the company ID. A customer belongs to at most one company. Remember that every later `PUT` on the customer must include `company` too, because leaving it out unlinks them.

```bash title="cURL"
curl --request PUT "https://api.kustomerapp.com/v1/customers/$CUSTOMER_ID" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data "{\"company\": \"$COMPANY_ID\"}"
```

```bash title="kusty"
kusty api PUT /v1/customers/$CUSTOMER_ID --field company=$COMPANY_ID
```

**Step 2.** [`GET /v1/customers/{id}`](https://developer.kustomer.com/api/core-resources/get-customer-by-id.md). Read the customer with `include=company` to get the company record alongside it in one call, for example to show the account name and tier next to the person.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/customers/$CUSTOMER_ID?include=company" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v1/customers/$CUSTOMER_ID --query include=company
```

> To link many customers at once, send `{ "id", "company" }` items to [`PUT /v1/customers/bulk`](https://developer.kustomer.com/api/core-resources/bulk-batch-update-customers), up to 100 per request.

#### 3. Put a subsidiary under its parent company

Mirror a corporate structure, such as a parent account and its regional offices, in Kustomer's company hierarchy.

**Step 1.** [`POST /v1/kedge/{id}/parent`](https://developer.kustomer.com/api/core-resources/set-a-companys-parent.md). Call this on the child company with the parent's ID as `parentId`. A company has one parent per tree, so this replaces any parent it already had. Trees are named; leave out `name` to use the default `company_hierarchy`. Making a company its own parent or creating a cycle fails with `400`, and a `409` means another write to the same tree was in progress, so retry.

```bash title="cURL"
curl --request POST "https://api.kustomerapp.com/v1/kedge/$CHILD_ID/parent" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data "{\"parentId\": \"$PARENT_ID\"}"
```

```bash title="kusty"
kusty api POST /v1/kedge/$CHILD_ID/parent --field parentId=$PARENT_ID
```

**Step 2.** [`GET /v1/kedge/{id}`](https://developer.kustomer.com/api/core-resources/get-a-company-hierarchy-node.md). Read the child's place in the tree. `parent` is the edge to its parent, `children` is one page of its direct children, and `breadcrumbs` runs from the root down to the company itself, ready to show as a path such as "Acme Corp › Acme EMEA".

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/kedge/$CHILD_ID" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v1/kedge/$CHILD_ID | jq -r '[.data.attributes.breadcrumbs[].displayName] | join(" › ")'
```

> A tree can be at most 20 levels deep and hold at most 2,000 companies. [Model company hierarchies](https://developer.kustomer.com/docs/guides/company-hierarchy) covers multiple trees and moving whole branches.

#### 4. Delete a company that has subsidiaries

Remove a company you no longer need, first detaching any child companies that would block the delete.

**Step 1.** [`GET /v1/kedge/{id}`](https://developer.kustomer.com/api/core-resources/get-a-company-hierarchy-node.md). List the company's direct children. Each item in `children` is an edge whose `targetId` is a child company ID. Pass `name` if the company is in a tree other than `company_hierarchy`.

```bash title="cURL"
curl "https://api.kustomerapp.com/v1/kedge/$COMPANY_ID" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api GET /v1/kedge/$COMPANY_ID | jq -r '.data.attributes.children[].attributes.targetId'
```

**Step 2.** [`DELETE /v1/kedge/{id}/parent`](https://developer.kustomer.com/api/core-resources/remove-a-companys-parent.md). For each child, remove its parent edge. The child becomes a root and keeps its own children. This takes the child's company ID, not the edge ID.

```bash title="cURL"
curl --request DELETE "https://api.kustomerapp.com/v1/kedge/$CHILD_ID/parent" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```

```bash title="kusty"
kusty api DELETE /v1/kedge/$CHILD_ID/parent --confirm --yes
```

**Step 3.** [`PUT /v1/companies/{id}`](https://developer.kustomer.com/api/core-resources/update-company-attributes.md). There's no `DELETE` for companies; you delete one by sending `deleted: true`. If a child is still attached in any tree, the API answers `409 Conflict` and names the first blocking child and its tree; detach it with `name` set to that tree and try again.

```bash title="cURL"
curl --request PUT "https://api.kustomerapp.com/v1/companies/$COMPANY_ID" \
  --header "Authorization: Bearer $KUSTOMER_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{"deleted": true}'
```

```bash title="kusty"
kusty api PUT /v1/companies/$COMPANY_ID --field deleted:=true
```

### Example object

A real record from [`GET /v1/companies`](https://developer.kustomer.com/api/core-resources/get-companies.md):

```json
{
  "type": "company",
  "id": "58224b3eaa5f92110005d61e",
  "attributes": {
    "name": "foobar Company Name",
    "externalId": "foobar",
    "createdAt": "2016-11-08T22:01:34.620Z",
    "updatedAt": "2016-11-08T22:11:35.776Z",
    "modifiedAt": "2016-11-08T22:11:35.776Z",
    "tags": [
      "58224d97d4e96711004ecc56"
    ]
  },
  "relationships": {
    "org": {
      "links": {
        "self": "/v1/orgs/57f29863a1dbf61100e6aa92"
      },
      "data": {
        "type": "org",
        "id": "57f29863a1dbf61100e6aa92"
      }
    },
    "createdBy": {
      "links": {
        "self": "/v1/users/58190b991f2932100010d683"
      },
      "data": {
        "type": "user",
        "id": "58190b991f2932100010d683"
      }
    },
    "modifiedBy": {
      "links": {
        "self": "/v1/users/58190b991f2932100010d683"
      },
      "data": {
        "type": "user",
        "id": "58190b991f2932100010d683"
      }
    }
  },
  "links": {
    "self": "/v1/companies/58224b3eaa5f92110005d61e"
  }
}
```

Fields:

- `attributes.name` (string): The company's name, 3 to 256 characters. The only field required on create.
- `attributes.externalId` (string): The account's ID in your CRM or other system, up to 256 characters. Find the company again with `GET /v1/companies?externalId=…`.
- `attributes.createdAt` (string): When the company was created in Kustomer. You can set it on create when importing, along with `importedAt`.
- `attributes.modifiedAt` (string): When the company was last changed.
- `attributes.tags` (array): Tag IDs, up to 20. Sending `tags` on an update replaces the whole list.
- `relationships.createdBy` (object): The user or API key that created the company.

### Relationships

- Referenced by **Customers** via `relationships.company`: The company this customer belongs to. A customer has at most one; set it by sending the company ID as `company`, and resend it on every `PUT`, because leaving it out unlinks the customer.
- Referenced by **KObjects (custom objects)** via `relationships.company`: The company whose timeline shows this KObject, set with `company` when you create it. List them with `GET /v1/companies/{id}/klasses/{name}`.

### Permissions

Fewest roles for a read-only integration: `org.permission.company.read`. For every endpoint: `org.permission.company.update`, `org.permission.company.read`, `org.permission.company.create`.

### Events

Workflow triggers:

- `kustomer.company.create` (Company Created): A company is created
- `kustomer.company.update` (Company Updated): A company changes

Workflow actions:

- `kustomer.company.create` (Company: Create): required inputs `name`
- `kustomer.company.update` (Company: Update): required inputs `id`
- `kustomer.company.find` (Company: Lookup (By ID)): required inputs `identifier`
- `kustomer.company.find-by-external-id` (Company: Lookup (By External ID)): required inputs `externalId`

## Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `page` | integer | no | Page number of results to return. |
| `pageSize` | integer | no | Number of results to return per page. |
| `externalId` | string | no | Unique external ID of the company |
| `filter` | string | no | Company name to use as a filter |

## Responses

### 200

OK

- `meta` (object, required)
  - `pageSize` (integer, required)
  - `page` (integer, required)
- `data` (array<object>, required)
  - `type` (string, required)
  - `id` (string, required)
  - `attributes` (object, required)
    - `name` (string, required)
    - `externalId` (string, required)
    - `createdAt` (string, required)
    - `updatedAt` (string, required)
    - `modifiedAt` (string, required)
    - `tags` (array<string>, required)
  - `relationships` (object, required)
    - `org` (object, required)
    - `createdBy` (object, required)
    - `modifiedBy` (object, required)
  - `links` (object, required)
    - `self` (string, required)
- `links` (object, required)
  - `self` (string, required)
  - `first` (string, required)
  - `prev` (string, required, nullable)
  - `next` (string, required, nullable)

```json
{
  "meta": {
    "pageSize": 100,
    "page": 1
  },
  "data": [
    {
      "type": "company",
      "id": "58224b3eaa5f92110005d61e",
      "attributes": {
        "name": "foobar Company Name",
        "externalId": "foobar",
        "createdAt": "2016-11-08T22:01:34.620Z",
        "updatedAt": "2016-11-08T22:11:35.776Z",
        "modifiedAt": "2016-11-08T22:11:35.776Z",
        "tags": [
          "58224d97d4e96711004ecc56"
        ]
      },
      "relationships": {
        "org": {
          "links": {
            "self": "/v1/orgs/57f29863a1dbf61100e6aa92"
          },
          "data": {
            "type": "org",
            "id": "57f29863a1dbf61100e6aa92"
          }
        },
        "createdBy": {
          "links": {
            "self": "/v1/users/58190b991f2932100010d683"
          },
          "data": {
            "type": "user",
            "id": "58190b991f2932100010d683"
          }
        },
        "modifiedBy": {
          "links": {
            "self": "/v1/users/58190b991f2932100010d683"
          },
          "data": {
            "type": "user",
            "id": "58190b991f2932100010d683"
          }
        }
      },
      "links": {
        "self": "/v1/companies/58224b3eaa5f92110005d61e"
      }
    },
    {
      "type": "company",
      "id": "58224b3eaa5f92110005d61d",
      "attributes": {
        "name": "foobar2 Company Name",
        "externalId": "foobar2",
        "createdAt": "2016-11-08T22:01:34.620Z",
        "updatedAt": "2016-11-08T22:11:35.776Z",
        "modifiedAt": "2016-11-08T22:11:35.776Z",
        "tags": [
          "58224d97d4e96711004ecc56"
        ]
      },
      "relationships": {
        "org": {
          "links": {
            "self": "/v1/orgs/57f29863a1dbf61100e6aa92"
          },
          "data": {
            "type": "org",
            "id": "57f29863a1dbf61100e6aa92"
          }
        },
        "createdBy": {
          "links": {
            "self": "/v1/users/58190b991f2932100010d683"
          },
          "data": {
            "type": "user",
            "id": "58190b991f2932100010d683"
          }
        },
        "modifiedBy": {
          "links": {
            "self": "/v1/users/58190b991f2932100010d683"
          },
          "data": {
            "type": "user",
            "id": "58190b991f2932100010d683"
          }
        }
      },
      "links": {
        "self": "/v1/companies/58224b3eaa5f92110005d61d"
      }
    }
  ],
  "links": {
    "self": "/v1/companies?filter=foobar&page=1&pageSize=100",
    "first": "/v1/companies?filter=foobar&page=1&pageSize=100",
    "prev": null,
    "next": null
  }
}
```

### 401

Unauthorized

### 403

Forbidden

## Example request

```bash
curl --request GET \
  --url 'https://api.kustomerapp.com/v1/companies' \
  --header "Authorization: Bearer $KUSTOMER_API_KEY"
```
