# Create Merchant

Creates a sub-merchant under the authenticated partner and starts underwriting lifecycle tracking.
For the **partner API** contract, `id` is server-managed and is not accepted in the request payload.
Resolve derives/assigns the merchant identifier from merchant naming inputs (`dba_name` or `legal_business_name`) with random alphanumeric fallback for collisions.
Core merchant validation includes:
- `business_phone` must be a valid US phone number
- `formation_state` must map to a valid US state
- US business addresses validate `state` and `postal_code`
- beneficial owner US addresses validate `state` and `postal_code`
- `authorized_signer.phone`, when provided, must be a valid US phone number
- `ein` must be a valid EIN format
- banking fields validate account-number shape and ABA routing number format
- `bank_account_number` must be different from `bank_routing_number`

This endpoint also supports optional inline document URL ingestion. If document arrays are provided
(`bank_statements`, `financial_statements`, `credit_references`, `personal_guarantee`, `other_documents`),
Resolve queues `download_url` ingestion jobs equivalent to the document endpoint.
Inline document requests require:
- `filename` with an extension
- supported `filetype` for the merchant underwriting document profile
- `download_url` using `http` or `https`
- matching filename extension and `filetype`

Merchant creation is not rolled back for inline document ingestion failures.
Inline download dispatch is performed after database commit. Dispatch failures are surfaced per-item in
`document_ingestion.results`, and the affected merchant document/file metadata is marked failed even though
the merchant and some/all document rows were already persisted.

Endpoint: POST /merchants
Version: partners-v1
Security: bearerAuth, basicAuth

## Request fields (application/json):

  - `reference_id` (string)
    Partner-supplied identifier for this merchant in your own system.
Stored as provided and returned on every merchant response. Filter on it with
`filter[reference_id][eq]=<value>` when listing merchants.
Values are not required to be unique across your merchants, are limited to 255 characters,
and may not be blank. Send `null` to clear a previously stored value.
    Example: partner-crm-12345

  - `legal_business_name` (string, required)
    Example: Acme Supply LLC

  - `business_address` (object, required)

  - `business_address.line1` (string, required)
    Example: 100 Main St

  - `business_address.line2` (string)
    Example: Suite 200

  - `business_address.city` (string, required)
    Example: Austin

  - `business_address.state` (string, required)
    Example: TX

  - `business_address.postal_code` (string, required)
    Example: 78701

  - `business_address.country` (string, required)
    Example: US

  - `business_email` (string, required)
    Example: ops@acmesupply.com

  - `business_phone` (string, required)
    Business phone number. Must be a valid US phone number and is normalized to E.164.
    Example: +15125550123

  - `entity_type` (string, required)
    Enum: "corporation", "llc", "sole_proprietorship", "partnership", "non_profit"

  - `formation_state` (string, required)
    Business formation state. Must map to a valid US state and is normalized to the state code.
    Example: TX

  - `ein` (string, required)
    Employer Identification Number. Must be a valid EIN format.
    Example: 12-3456789

  - `dba_name` (string)
    Example: Acme Industrial

  - `annual_revenue` (integer)
    Example: 4500000

  - `years_in_business` (integer)
    Example: 6

  - `industry` (string)
    Example: Manufacturing

  - `business_description` (string)
    Example: Industrial hardware distributor

  - `website` (string)
    Example: https://acmesupply.com

  - `estimated_monthly_net_terms_volume` (integer)
    Example: 350000

  - `beneficial_owners` (array)
    Initial beneficial owner list.

  - `beneficial_owners.first_name` (string, required)
    Example: John

  - `beneficial_owners.last_name` (string, required)
    Example: Owner

  - `beneficial_owners.date_of_birth` (string, required)
    Example: 1987-04-14

  - `beneficial_owners.ssn_last_4` (string, required)
    Example: 1234

  - `beneficial_owners.ownership_percentage` (number)
    Example: 35

  - `authorized_signer` (object)

  - `authorized_signer.first_name` (string)
    Example: Jane

  - `authorized_signer.last_name` (string)
    Example: Doe

  - `authorized_signer.email` (string)
    Example: jane.doe@acmesupply.com

  - `authorized_signer.title` (string)
    Example: Controller

  - `authorized_signer.phone` (string)
    Example: +15125550123

  - `plaid_access_token` (string)
    Plaid access token when a bank connection has already been established.
    Example: access-sandbox-1234567890

  - `bank_account_number` (string)
    Bank account number. Must satisfy Resolve account-number validation and must be different from
`bank_routing_number`.
    Example: ****6789

  - `bank_routing_number` (string)
    ABA routing number. Must be a valid routing number.
    Example: *****021

  - `bank_statements` (array)
    Optional document ingestion on merchant create.
Each item queues a background download job (equivalent to calling the document endpoint with `download_url`).

  - `bank_statements.filename` (string, required)
    Original filename for the remote file.
The filename must include an extension, and that extension must match `filetype`.
    Example: bank_statement_2026_01.pdf

  - `bank_statements.filetype` (string, required)
    MIME type for the remote file.
Must be a supported MIME type for the merchant underwriting document validation profile.
    Example: application/pdf

  - `bank_statements.download_url` (string, required)
    Remote file URL. Only `http` and `https` URLs are accepted.
    Example: https://partner-files.example.com/bank_statement_2026_01.pdf

  - `financial_statements` (array)
    Optional inline `financial_statements` document ingestion requests.

  - `credit_references` (array)
    Optional inline `credit_references` document ingestion requests.

  - `personal_guarantee` (array)
    Optional inline `personal_guarantee` document ingestion requests.

  - `other_documents` (array)
    Optional inline `other` document ingestion requests.

## Response 200 fields (application/json):

  - `id` (string)
    Resolve merchant identifier (lowercase alphanumeric).
For partner API create flows, ID assignment behavior is:
- Resolve may derive a human-friendly alphanumeric candidate from merchant naming fields.
- If the candidate collides with an existing merchant ID, Resolve generates a random lowercase alphanumeric ID.
    Example: mrc_1234567890abcdef

  - `reference_id` (string)
    Partner-supplied identifier for this merchant in your own system. `null` when never set.
    Example: partner-crm-12345

  - `legal_business_name` (string)
    Example: Acme Supply LLC

  - `dba_name` (string)
    Example: Acme Industrial

  - `business_address` (object)

  - `business_address.line1` (string, required)
    Example: 100 Main St

  - `business_address.line2` (string)
    Example: Suite 200

  - `business_address.city` (string, required)
    Example: Austin

  - `business_address.state` (string, required)
    Example: TX

  - `business_address.postal_code` (string, required)
    Example: 78701

  - `business_address.country` (string, required)
    Example: US

  - `business_email` (string)
    Example: ops@acmesupply.com

  - `business_phone` (string)
    Example: +15125550123

  - `entity_type` (string)
    Enum: "corporation", "llc", "sole_proprietorship", "partnership", "non_profit"

  - `formation_state` (string)
    Example: TX

  - `industry` (string)
    Example: Manufacturing

  - `website` (string)
    Example: https://acmesupply.com

  - `underwriting_status` (string)
    Current underwriting lifecycle status for the merchant.
    Example: pending

  - `seller_amount_approved` (integer)
    Merchant approved limit (MAL), when available.
    Example: 50000

  - `active_subscription` (object)

  - `active_subscription.id` (string)
    Example: sub_1234567890abcdef

  - `active_subscription.tier` (string)
    Example: trial

  - `document_ingestion` (object)

  - `document_ingestion.requested_count` (integer)
    Example: 2

  - `document_ingestion.queued_count` (integer)
    Example: 1

  - `document_ingestion.failed_count` (integer)
    Example: 1

  - `document_ingestion.results` (array)

  - `document_ingestion.results.document_id` (string)
    Example: md_1234567890abcdef

  - `document_ingestion.results.document_type` (string)
    Enum: "bank_statements", "financial_statements", "credit_references", "personal_guarantee", "other"

  - `document_ingestion.results.filename` (string)

  - `document_ingestion.results.download_url` (string)

  - `document_ingestion.results.status` (string)
    Enum: "queued", "failed"

  - `document_ingestion.results.error_code` (string)

  - `document_ingestion.results.error_message` (string)

  - `created_at` (string)
    Example: 2026-02-26T10:00:00.000Z

  - `updated_at` (string)
    Example: 2026-02-26T10:05:00.000Z

## Response 400 fields (application/json):

  - `error` (object)

  - `error.message` (string)
    A short string, describing error details
    Example: Validation error

  - `error.type` (string)
    A short string, describing error type
    Enum: "validation_error"

  - `error.details` (array)

  - `error.details.path` (string)
    Path to the field failed validation
    Example: path.to.field

  - `error.details.message` (string)
    Detailed description of the error
    Example: `[field]` is required

## Response 401 fields (application/json):

  - `error` (object)

  - `error.message` (string)
    A short string, describing error details
    Example: Invalid merchant credentials

  - `error.type` (string)
    A short string, describing error type
    Enum: "authentication_error"

## Response 404 fields (application/json):

  - `error` (object)

  - `error.message` (string)
    A short string, describing error details
    Example: [entity] not found

  - `error.type` (string)
    A short string, describing error type
    Enum: "not_found_error"

## Response 429 fields (application/json):

  - `error` (object)

  - `error.message` (string)
    A short string, describing error details
    Example: Too many requests

  - `error.type` (string)
    A short string, describing error type
    Enum: "rate_limit_error"

