> ## Documentation Index
> Fetch the complete documentation index at: https://developers.staging01.melio.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Entities

> Onboard and manage the businesses you operate on behalf of, including their profile, compliance details, and payment eligibility.

An **entity** is a business you onboard and operate on behalf of: its profile, compliance details, and per-operation limitations. It combines an organization and its owner into a single record that Melio screens against KYC and compliance requirements. A business must clear those requirements before it can send payments.

Only `business` entities are supported today.

## Endpoints

| Method  | Path                   | Description                                                             |
| ------- | ---------------------- | ----------------------------------------------------------------------- |
| `GET`   | `/entities`            | List your entities, newest first. Filter by `externalId` or `metadata`. |
| `POST`  | `/entities`            | Create an entity.                                                       |
| `GET`   | `/entities/{entityId}` | Retrieve one entity.                                                    |
| `PATCH` | `/entities/{entityId}` | Update an entity (partial).                                             |

`{entityId}` is an entity id (`ent_<uuid>`) or the sentinel `me`, which resolves to the partner's sole entity. The same value is accepted in the `Melio-Entity-Id` header used by other resources.

## Entity fields

Supplied when you create an entity. Every field below except `externalId`, `metadata`, `website`, and `description` is required on create.

| Field          | Type   | Description                                                                                                  |
| -------------- | ------ | ------------------------------------------------------------------------------------------------------------ |
| `type`         | enum   | Entity type discriminator. Only `business` is supported.                                                     |
| `name`         | string | Company (doing-business-as) name shown on transactions. 3 to 100 characters.                                 |
| `legalName`    | string | Full legal business name as it appears on the tax return. 3 to 100 characters. **Immutable after creation.** |
| `phoneNumber`  | string | Business phone number. At least 9 digits.                                                                    |
| `businessType` | enum   | One of `partnership`, `sole-proprietorship`, `llc`, `corporation`, `trust`, `non-profit`, `municipality`.    |
| `taxInfo`      | object | Business tax identifier. See below. **Immutable after creation.**                                            |
| `industry`     | object | `naicsCode` (NAICS classification, digits) and optional `name`.                                              |
| `contact`      | object | Organization-level contact person: `firstName`, `lastName` (each at least 2 characters).                     |
| `address`      | object | Physical business (mailing) address. May not be a PO box.                                                    |
| `legalAddress` | object | Registered legal address. **Immutable after creation.**                                                      |
| `owner`        | object | The account owner. See below.                                                                                |
| `website`      | string | Optional.                                                                                                    |
| `description`  | string | Optional.                                                                                                    |
| `externalId`   | string | Optional. Your own id for the entity, unique per partner. See [External IDs](/docs/external-ids).                 |
| `metadata`     | object | Optional. Your own key/value context. See [Metadata](/docs/metadata).                                             |

### Tax info

```json theme={null}
{ "type": "ein", "identifier": "12-3456789" }
```

* `type` is one of `ein`, `ssn`, or `itin`. `ein` is accepted for every business type; `ssn` is accepted only for `sole-proprietorship` and `trust`. `itin` is retained for backward compatibility but is **no longer accepted for any** business type.
* `identifier` is a 9-digit tax id, optionally dash-separated. It is write-only: responses return only `taxInfo.identifierLast4`.

### Address

`line1`, `city`, `state` (two-letter US code), and `postalCode` are required; `line2`, `aptNumber`, and `countryCode` (defaults to `US`) are optional. The physical `address` may not be a PO box.

### Owner

```json theme={null}
{
  "firstName": "Jane",
  "lastName": "Doe",
  "email": "jane.doe@acmesupplies.com",
  "dateOfBirth": "1985-04-12"
}
```

`firstName`, `lastName`, `email`, and `dateOfBirth` are required and are collected for sanctions screening; `phoneNumber` is optional. The owner must be between 18 and 120 years old, and stricter date-of-birth validation applies when `taxInfo.type` is `ssn`.

## Creating an entity

```bash theme={null}
curl -X POST https://api.example.com/v2/entities \
  -H "Authorization: Bearer <api-key>" \
  -H "Idempotency-Key: 1f8e2c3a-9b47-4d21-8a6e-2c0f5b7d9e14" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "business",
    "externalId": "partner-biz-1234",
    "name": "Acme Supplies",
    "legalName": "Acme Supplies LLC",
    "phoneNumber": "+12125551234",
    "businessType": "llc",
    "taxInfo": { "type": "ein", "identifier": "12-3456789" },
    "industry": { "naicsCode": "424410" },
    "contact": { "firstName": "Jane", "lastName": "Doe" },
    "address": { "line1": "350 5th Ave", "city": "New York", "state": "NY", "postalCode": "10118" },
    "legalAddress": { "line1": "350 5th Ave", "city": "New York", "state": "NY", "postalCode": "10118" },
    "owner": {
      "firstName": "Jane",
      "lastName": "Doe",
      "email": "jane.doe@acmesupplies.com",
      "dateOfBirth": "1985-04-12"
    }
  }'
```

A successful create returns `201` with the entity, including its `id` (`ent_<uuid>`). Send an `Idempotency-Key` so retries are safe. See [Idempotency](/docs/idempotency).

### Direct vs. platform partners

* A **direct partner** manages a single entity, its own business. A second `POST /entities` returns `409 conflict_error` / `DUPLICATE_ENTITY`.
* A **platform partner** can create as many entities as it needs, one per business it serves.

### Conflicts

| Status         | `code`                  | Meaning                                             |
| -------------- | ----------------------- | --------------------------------------------------- |
| `409 Conflict` | `DUPLICATE_ENTITY`      | A direct partner already has an entity.             |
| `409 Conflict` | `DUPLICATE_EXTERNAL_ID` | The `externalId` is already used by another entity. |

On `DUPLICATE_EXTERNAL_ID` you can recover by fetching the existing entity with `GET /entities?externalId=<yourId>` and reusing it, which makes queued retries safe once the idempotency-key window has elapsed.

## Updating an entity

`PATCH /entities/{entityId}` changes only the fields you send.

```bash theme={null}
curl -X PATCH https://api.example.com/v2/entities/ent_7c9e6679-7425-40de-944b-e07fc1f90ae7 \
  -H "Authorization: Bearer <api-key>" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Acme Supplies Co", "website": "https://acme-supplies.example.com" }'
```

<Warning>
  `legalName`, `legalAddress`, and `taxInfo` are fixed once the entity is created. Including any of them in a `PATCH` returns `400 VALIDATION_ERROR`.
</Warning>

## Payment eligibility

Creating an entity does not clear it to transact. Melio screens the profile against KYC and compliance requirements, and the result is exposed as per-operation limitations. Check them with `GET /limitations`:

```bash theme={null}
curl https://api.example.com/v2/limitations \
  -H "Authorization: Bearer <api-key>" \
  -H "Melio-Entity-Id: ent_7c9e6679-7425-40de-944b-e07fc1f90ae7"
```

Each capability reports whether an operation (for example `payment.domestic:write`) is `allowed`, and if not, the `reasons` why. A `MissingInformation` reason lists the entity fields that still need to be supplied in `missingFields`:

```json theme={null}
{
  "capabilities": [
    {
      "operation": "payment.domestic:write",
      "allowed": false,
      "reasons": [
        {
          "code": "MissingInformation",
          "message": "Additional information is required before this business can send payments.",
          "missingFields": ["taxInfo"]
        }
      ]
    }
  ]
}
```

Resolve each `missingFields` entry with a `PATCH /entities/{entityId}`, then re-check. Rather than polling, subscribe to the `api.limitation.updated` [webhook](/docs/webhooks) event and re-fetch when it fires. See [Limitations](/docs/limitations) for the full model, and [Errors](/docs/errors) for the `BUSINESS_NOT_ELIGIBLE` response returned when you attempt a blocked operation.

## Related

* [Limitations](/docs/limitations) - per-operation eligibility and reasons.
* [External IDs](/docs/external-ids) - correlate entities with your own records.
* [Idempotency](/docs/idempotency) - safe entity creation.
