Skip to main content
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. Creating an entity also requires the business’s acceptance of the Melio terms of service, which you attest to in the request. See Terms acceptance.

Endpoints

{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.

Tax info

  • type is one of ein, ssn. ein is accepted for every business type; ssn is accepted only for sole-proprietorship and trust.
  • 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

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.

Terms acceptance

An entity cannot be created unless the business has accepted the Melio terms of service. You own the screen where the business accepts, so termsAcceptance is your attestation that the business was shown the terms and accepted them.
Both fields are required. acceptedAt must:
  • Carry a UTC offset, such as Z or +09:00, so it identifies one unambiguous instant. A timestamp without an offset is rejected. Any timezone is fine.
  • Be within the last 90 days.
  • Be no more than 14 hours ahead of Melio’s clock, which allows for a skewed clock on your side.
Melio stores the acceptance as an immutable record alongside the entity, in the same operation that creates it: an entity is never created without one. Entity responses include it as termsAcceptance:
The response returns only acceptedAt.

Creating an entity

A successful create returns 201 with the entity, including its id (ent_<uuid>) and the recorded termsAcceptance. Send an Idempotency-Key so retries are safe. See 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. Each business must accept the terms, so send a termsAcceptance for every entity you create.

Validation errors

A missing or invalid termsAcceptance returns 400 VALIDATION_ERROR and no entity is created.

Conflicts

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.
legalName, legalAddress, and taxInfo are fixed once the entity is created. Including any of them in a PATCH returns 400 VALIDATION_ERROR.
termsAcceptance is recorded when the entity is created and isn’t part of PATCH.

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:
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:
Resolve each missingFields entry with a PATCH /entities/{entityId}, then re-check. Rather than polling, subscribe to the api.limitation.updated webhook event and re-fetch when it fires. See Limitations for the full model, and Errors for the BUSINESS_NOT_ELIGIBLE response returned when you attempt a blocked operation.