> This page is for version v6.0 (default).
> For other versions, use one of these documentation indexes:
> - v6.0 (default): https://docs.zip.tax/v-6-0/llms.txt
> - v5.0: https://docs.zip.tax/v-5-0/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.zip.tax/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.zip.tax/_mcp/server.

# Self-Managed Merchants

A self-managed merchant is created with `merchantType: "self-managed"`. No
TaxCloud invite is sent, and the merchant is active the moment the create call
returns — there is no account-setup step to wait on.

Under this model, your platform tracks the merchant's nexus footprint on
Ziptax: the physical locations they operate from and the states where they
have crossed economic nexus thresholds. The merchant remains responsible for
their own compliance — registration, filing, and remittance. If you want
TaxCloud to handle compliance end to end instead, use a
[TaxCloud-connected merchant](taxcloud-connected-merchants).

## Create a self-managed merchant

Call `POST /merchant/create` with `merchantType` set to `self-managed`. The API
default is `taxcloud`, which starts the TaxCloud invite process, so you must pass
`self-managed` explicitly to create a self-managed merchant.

#### cURL

```bash
curl -X POST "https://api.zip-tax.com/merchant/create" \
  -H "X-API-KEY: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantName": "Acme Outfitters",
    "contactFirst": "Daniel",
    "contactLast": "Smith",
    "contactEmail": "daniel@acmeoutfitters.example",
    "referenceId": "acct-10482",
    "merchantType": "self-managed"
  }'
```

Only `merchantName` is required. `referenceId` is the identifier you use in
your own system for this merchant. The `sendTaxcloudInvite` field is ignored
when `merchantType` is `self-managed` — no invite is ever sent to a
self-managed merchant.

A successful call returns `201 Created`:

```json
{
  "status": "success",
  "message": "merchant created successfully",
  "merchantId": "6b3c1f5e-2a8d-4c9b-9f2e-1d7a4b6c8e10"
}
```

Store the `merchantId` (a UUID); you'll use it in every subsequent call for
this merchant.

Two error cases to plan for:

* **Company name not set.** Your account must have a Company Name configured
  before you can create any merchant. Without one, the API returns `400` with
  the message `Please add a Company Name in the General settings page before
  creating a merchant.`
* **Duplicate merchant.** Creating a duplicate — for example, reusing a
  `referenceId` that already belongs to another merchant in your account —
  returns `409 Conflict`.

## How self-managed merchants appear on reads

`POST /merchant/get` and `GET /merchant/list` do not return `merchantType`.
Instead, the compliance model is visible through the `status` field: a
self-managed merchant always reports `status: "external_compliance"`,
meaning compliance is managed outside TaxCloud.

```json
{
  "merchantId": "6b3c1f5e-2a8d-4c9b-9f2e-1d7a4b6c8e10",
  "merchantName": "Acme Outfitters",
  "contactFirst": "Daniel",
  "contactLast": "Smith",
  "contactEmail": "daniel@acmeoutfitters.example",
  "status": "external_compliance",
  "referenceId": "acct-10482"
}
```

Self-managed merchants never move through the TaxCloud lifecycle statuses
(`taxcloud_invited`, `taxcloud_connected`, `taxcloud_disconnected`) unless you
later [invite them to TaxCloud](#inviting-a-self-managed-merchant-to-taxcloud).

## What your platform manages

For a self-managed merchant, your platform records the merchant's nexus
footprint on Ziptax. This has two parts:

* **Physical nexus** — the locations the merchant operates from: offices,
  stores, warehouses, inventory (including FBA), employees, property, and
  temporary presence such as trade shows. Manage these through the
  `/merchant/nexus/*` endpoints or the platform UI. See
  [Nexus Management](nexus-management).
* **Economic thresholds** — the states where the merchant has crossed an
  economic nexus threshold from sales activity. Economic nexus is derived from
  sales activity rather than declared, so it is not something you record through
  the nexus endpoints. See [Economic Thresholds](economic-thresholds).

Ziptax does not require a minimum number of locations. If a merchant has no
physical locations recorded, Ziptax does not track physical nexus for them.

## Calculating tax

You have two options for a self-managed merchant, and both work with your Ziptax
API key alone — no merchant credentials involved.

**Cart calculation.** `POST /merchant/cart/calculate` takes a full cart — origin,
destination, and line items — and returns the tax due on each line. For a
self-managed merchant, Ziptax calculates it with its own rate engine, applying
sourcing rules, product taxability codes, and state freight rules. See
[Self-Managed Cart Calculation](self-managed-cart-calculation) for the contract.

**Rate lookup.** The [rate endpoints](../rest-api/overview) return the combined
rate and per-jurisdiction breakdown for a single US address, coordinate pair, or
postal code. Use these when you want the rate itself rather than a calculated
cart.

Cart calculation does **not** check the merchant's nexus footprint before
calculating: it returns the rate for the sourced address whether or not the
merchant has an obligation to collect there. Deciding where the merchant must
collect stays with you and the merchant.

## What else is not available

Cart calculation is the only [Merchant Transactions](transactions) endpoint a
self-managed merchant can use, and it is stateless — nothing is stored, so the
result cannot be turned into an order.

The remaining transaction endpoints (the `order/*` and `cert/*` operations, and
`refund/create`) forward requests to TaxCloud using compliance credentials
stored for the merchant. A self-managed merchant has no TaxCloud credentials, so
each of those calls returns `403`. They become available once a merchant is
[TaxCloud-connected](taxcloud-connected-merchants) with credentials set.

## Inviting a self-managed merchant to TaxCloud

A self-managed merchant can later be invited to TaxCloud, either from the
platform UI or through the API. This sends the TaxCloud invite email to the
merchant's contact and converts the merchant to the connected model. Because it
creates a [TaxCloud-connected merchant](taxcloud-connected-merchants), the
conversion is an Enterprise plan feature.

To convert through the API, send `setMerchantType` on
[`POST /merchant/update`](/api-reference/merchant/update-merchant). Nothing else
is required, since the invite goes to the `contactEmail` already stored for the
merchant:

```json
{
  "merchantId": "2c0534ea-eb8a-4732-9cdb-2476f244029d",
  "setMerchantType": "taxcloud",
  "sendTaxcloudInvite": true
}
```

The merchant's `status` moves from `external_compliance` to `taxcloud_invited`.

To invite a different address, send an `update` block in the same request. It is
applied before the invite, so the new address is the one emailed:

```json
{
  "merchantId": "2c0534ea-eb8a-4732-9cdb-2476f244029d",
  "setMerchantType": "taxcloud",
  "update": {
    "merchantName": "Blue Ridge Outfitters",
    "contactEmail": "dana@blueridgeoutfitters.example"
  }
}
```

A merchant with no contact email on record cannot be invited, so give it one in
the `update` block when converting. Set `sendTaxcloudInvite` to `false` to
convert without emailing the merchant at all, for example when you plan to
attach an existing TaxCloud account with
[Set Merchant Credentials](/api-reference/merchant/set-merchant-credentials)
instead.

The conversion is reversible: sending `setMerchantType: "self-managed"` moves
the merchant back. That direction deletes any TaxCloud credentials stored for
the merchant, so returning to the connected model afterwards means connecting
their TaxCloud account again. Re-sending a merchant's current type changes
nothing and does not re-send the invite, so the request is safe to repeat.

Converting also changes how cart calculation behaves for that merchant: calls
run through TaxCloud from then on, rates for the same cart may differ from what
the Ziptax engine returned before, and taxability codes switch to TaxCloud's
vocabulary. Allow up to a minute for the routing change to take effect. See
[Moving a merchant between models](self-managed-cart-calculation#moving-a-merchant-between-models).

## Related

#### [Self-Managed Cart Calculation](self-managed-cart-calculation)

Calculate cart tax for a self-managed merchant with Ziptax's rate engine.

#### [Merchant Management](merchant-management)

Create, read, update, and delete merchants under your account.

#### [Nexus Management](nexus-management)

Record the physical locations that make up a merchant's nexus footprint.

#### [Economic Thresholds](economic-thresholds)

Track the states where a merchant has crossed an economic nexus threshold.

#### [TaxCloud-Connected Merchants](taxcloud-connected-merchants)

Let TaxCloud handle registration, filing, and remittance end to end.