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

# Update a merchant

PUT https://apps.runpayments.io/ords/relay/api/boarding/v1/merchants/{merchant_id}
Content-Type: application/json

Fully replace a merchant application and, optionally, change its status to retract or (re)send it for signature. Available only while the application is in the edit window — a `merchant_status` of `new` or `sent_for_signature`. Once signed or beyond, the record is locked and this returns `409`.

Semantics:
- **Full replace.** The request body is the complete merchant application (the same schema as `POST /merchants`); it replaces the merchant's data in full. Send the application as it should now stand — the typical flow is read-modify-write: `GET` the merchant, apply your changes, `PUT` it back.
- **`merchant_status: "new"`** retracts the application: every outstanding signature link is invalidated immediately. This is also the cancel flow — nothing is deleted, the record simply returns to `new`.
- **`merchant_status: "sent_for_signature"`** issues a fresh single-use signature link to the signer as updated in the same request; if the application was already out for signature it is retracted first, so retract and resend happen atomically.
- Any update to an application currently out for signature auto-retracts it back to `new`, so changed data can never sit under a live link. Include `merchant_status: "sent_for_signature"` in the same request to immediately reissue.
- `rep_code` and `platform` must match the existing application and cannot be changed on update.
- Sending can be expressed either way: `merchant_status: "sent_for_signature"`, or the create-style `auto_send_for_signature: true` when `merchant_status` is omitted. An explicit `merchant_status` always wins — `merchant_status: "new"` retracts and does not send even if `auto_send_for_signature` is true.

Status changes fire the standard `merchant.new` and `merchant.sent_for_signature` webhooks.


Reference: https://docs.runpayments.io/reference/reporting-boarding/boarding-api/update-merchant

## Authentication

- `Authorization` header (bearer token, required) — This API uses OAuth 2.0 for authentication.

## Request

### Path parameters

- `merchant_id` (integer, required) — The unique identifier for the merchant

### Body (application/json)

This endpoint expects an object.

- `dba_name` (string, required) — Doing Business As (DBA) name.
- `platform` (enum, required) — Currently supporting Fiserv and Payroc. Additional platforms may be added in the future. Must match the platform of the supplied `rep_code`.
  - Allowed values: `payroc`, `fiserv`
- `rep_code` (string, required) — Must be a rep_code that exists on your account. See the /rep_codes endpoint.
- `signer_email` (string, required) — Email address of the signer.
- `signer_first_name` (string, required) — First name of the signer.
- `signer_last_name` (string, required) — Last name of the signer.
- `signer_ownership_pct` (double, required) — Ownership percentage of the signer (0-100). The sum of the signer's and all additional owners' ownership percentages must not exceed 100.
- `addresses` (list of Address, optional) — List of addresses associated with the merchant.
- `annual_volume` (double, optional) — Annual transaction volume in dollars.
- `application_template_id` (double, optional) — ID of the application template to use. Must be an application template available to your rep codes. If provided, `mcc_code`, `business_desc`, transaction percentages, volume fields, `pricing`, `fees`, and `products` are taken from the template.
- `auto_send_for_signature` (boolean, optional) — If true, the application is emailed to the signer for signature once this request completes. On create (POST) this sends the initial signature request. On update (PUT) it (re)issues a fresh signature link and applies only when `merchant_status` is omitted — an explicit `merchant_status` takes precedence.
- `average_ticket` (double, optional) — Average transaction amount in dollars.
- `business_desc` (string, optional) — Description of the business.
- `customer_id` (double, optional) — Used if adding to an existing account.
- `fees` (Fees, optional) — Fee details for the merchant. See the /platform_fees endpoint for the fees available for each platform. Ignored if `application_template_id` is provided.
- `in_person_pct` (double, optional) — Percentage of in-person transactions. Must sum to 100 with `online_pct` and `telephone_pct`.
- `is_test` (boolean, optional) — If true, the merchant is created as a test record.
- `legal_name` (string, optional) — Legal name of the business.
- `mcc_code` (string, optional) — Merchant Category Code (MCC). See /mcc for valid values. Ignored if `application_template_id` is provided.
- `merchant_status` (enum, optional) — Optional status action. `new` retracts (invalidates outstanding signature links); `sent_for_signature` (re)issues a fresh signature link to the signer. Omit to update application data without a status change.
  - Allowed values: `new`, `sent_for_signature`
- `message` (string, optional) — Optional custom message included in the signature email. Only meaningful when `merchant_status` is `sent_for_signature`.
- `online_pct` (double, optional) — Percentage of online transactions. Must sum to 100 with `in_person_pct` and `telephone_pct`.
- `owners` (list of Owner, optional) — Additional non-signing owners. The signer is always submitted via the top-level `signer_*` fields; use this array only for other owners.
- `ownership_type` (enum, optional) — Additional platform-specific ownership types: **Fiserv** - `tax_exempt`, `public_corp`, `private_corp`. **Payroc** - `s_corp`, `c_corp`, `other`.
  - Allowed values: `llc`, `sole_proprietor`, `government`, `not_for_profit`, `partnership`
- `phone` (string, optional) — Phone number in the format `###-###-####`.
- `pricing` (Pricing, optional) — Pricing details for the merchant. See the /pricing_types endpoint for the pricing types and fields available for each platform. Ignored if `application_template_id` is provided.
- `products` (list of Product, optional) — List of products associated with the merchant. See the /products endpoint for the product catalog. Ignored if `application_template_id` is provided.
- `prospect_source` (string, optional) — Source attribution for the prospect record.
- `prospect_source_1` (string, optional) — Additional source attribution for the prospect record.
- `prospect_source_2` (string, optional) — Additional source attribution for the prospect record.
- `refund_policy` (enum, optional) — Refund policy.
  - Allowed values: `no_refunds`, `less_than_30_days`, `less_than_60_days`
- `seasonal` (boolean, optional) — Indicates if the business is seasonal.
- `seasonal_months` (string, optional) — Colon-delimited month numbers (e.g., 1:2:10 for January, February, and October). Required if `seasonal` is true.
- `services_provided_in` (enum, optional) — Timeframe for when services or goods are provided.
  - Allowed values: `0_7_days`, `8_14_days`, `15_30_days`, `over_30_days`
- `signer_dob` (string, optional) — Date of birth of the signer in the format mm/dd/yyyy.
- `signer_phone` (string, optional) — Phone number in the format `###-###-####`.
- `signer_res_address1` (string, optional) — Residential address line 1 of the signer.
- `signer_res_address2` (string, optional) — Residential address line 2 of the signer.
- `signer_res_city` (string, optional) — Residential city of the signer.
- `signer_res_state` (string, optional) — Residential state of the signer (uppercase 2-character abbreviation).
- `signer_res_zip` (string, optional) — Residential ZIP code of the signer.
- `signer_ssn` (string, optional) — Social Security number of the signer.
- `tax_id` (string, optional) — Tax identification number. Must be a 9-digit number (dashes allowed).
- `telephone_pct` (double, optional) — Percentage of telephone transactions. Must sum to 100 with `in_person_pct` and `online_pct`.
- `website` (string, optional) — Business website URL.
- `when_card_charged` (enum, optional) — When the card is charged.
  - Allowed values: `in_advance`, `on_delivery`
- `years_in_business` (double, optional) — Number of years the business has been operating.

## Response

### 200

Merchant updated successfully. Returns the full merchant record, the same shape as `GET /merchants/{merchant_id}`.

## Errors

### 400 Bad Request Error

Validation failure, a `rep_code`/`platform` mismatch, or a `merchant_status` other than `new`/`sent_for_signature`.

- `error` (string, optional) — Error code.
- `error_description` (string, optional) — Detailed error description.

### 401 Unauthorized Error

Unauthorized.

- `error` (string, optional) — Error code.
- `error_description` (string, optional) — Detailed error description.

### 404 Not Found Error

Merchant not found or not accessible.

- `error_message` (string, optional) — Description of the error (e.g., `merchant_id 123 not found.`).

### 409 Conflict Error

The application is locked (already signed or beyond) and can no longer be updated. The current `merchant_status` is included in the error message.

- `error` (string, optional) — Error code.
- `error_description` (string, optional) — Detailed error description.

## Types

### Address

- `address1` (string, optional) — Address line 1.
- `address2` (string, optional) — Address line 2.
- `city` (string, optional) — City.
- `state` (string, optional) — State (2-character abbreviation).
- `zip` (string, optional) — ZIP code.
- `address_type` (enum, optional) — Type of address.
  - Allowed values: `business`, `legal`, `mail_to`

### Fees

- `merchant_service_fees` (list of MerchantServicesFee, optional) — Platform-level fees. See the /platform_fees endpoint for the fees available for each platform.
- `pci_program` (PciProgram, optional) — PCI program selection. Valid types are `pci_concierge_fee_monthly` and `pci_annual_fee` for Fiserv, `platinum_monthly` and `platinum_annual` for Payroc.

### Owner

An additional non-signing owner of the business

- `first_name` (string, required) — First name of the owner.
- `last_name` (string, required) — Last name of the owner.
- `ownership_pct` (double, required) — Ownership percentage of the owner (0-100). The sum of the signer's and all additional owners' ownership percentages must not exceed 100.
- `email` (string, required) — Email address of the owner.
- `phone` (string, optional) — Phone number in the format `###-###-####`.
- `ssn` (string, optional) — Social Security number of the owner.
- `dob` (string, optional) — Date of birth of the owner in the format mm/dd/yyyy.
- `res_address1` (string, optional) — Residential address line 1 of the owner.
- `res_address2` (string, optional) — Residential address line 2 of the owner.
- `res_city` (string, optional) — Residential city of the owner.
- `res_state` (string, optional) — Residential state of the owner (uppercase 2-character abbreviation).
- `res_zip` (string, optional) — Residential ZIP code of the owner.

### Pricing

- `pricing_type` (enum, optional) — Pricing type. Please note that certain pricing types are only available for specific platforms. See the /pricing_types endpoint for the pricing types and fields available for each platform.
  - Allowed values: `ic_plus`, `flat_rate`, `merchant_surcharge_program`, `swipe_non_swipe`
- `discount_frequency` (enum, optional) — Fiserv ONLY. Frequency of discount.
  - Allowed values: `daily`, `monthly`
- `funding_rollup` (enum, optional) — Fiserv ONLY. Funding rollup preference.
  - Allowed values: `net_fees_and_deposits`, `individual_batches`, `separate_fees_and_deposits`
- `dues_and_assessments` (boolean, optional) — Fiserv ONLY. Automatically set to `true` for `ic_plus` pricing and `false` for `merchant_surcharge_program` pricing.
- `amex_program` (enum, optional) — AMEX program.
  - Allowed values: `no_american_express`, `amex_opt_blue`, `amex_esa`
- `amex_esa_number` (string, optional) — Required if `amex_program` is `amex_esa`. 10-digit AMEX ESA number. Not valid with `merchant_surcharge_program` pricing.
- `amex_esa_per_item` (double, optional) — Required if `amex_program` is `amex_esa`. Cost per item for AMEX ESA.
- `ic_plus` (ICPlus, optional) — IC Plus pricing details. Required if `pricing_type` is `ic_plus`.
- `swipe_non_swipe` (SwipeNonSwipe, optional) — Swipe/Non-swipe pricing details. Required if `pricing_type` is `swipe_non_swipe`.
- `merchant_surcharge_program` (MerchantSurchargeProgram, optional) — Merchant Surcharge pricing details. Required if `pricing_type` is `merchant_surcharge_program`.
- `flat_rate` (FlatRate, optional) — Flat Rate pricing details. Required if `pricing_type` is `flat_rate`.

### Product

- `platform_equipment_id` (integer, optional) — Platform-specific equipment identifier.
- `quantity` (integer, optional) — Quantity of the product.
- `product_id` (string, optional) — Product identifier. See the /products endpoint.
- `fees` (list of ProductFee, optional) — Array of fees associated with the product.

### MerchantServicesFee

- `fee_id` (string, optional) — Type of fee. Some fees are only available for specific platforms. See the /platform_fees endpoint.
- `cost` (double, optional, nullable) — Amount in dollars. Can be null for some fees.

### PciProgram

- `type` (string, optional) — Type of PCI program. Valid values are `pci_concierge_fee_monthly` and `pci_annual_fee` for Fiserv, `platinum_monthly` and `platinum_annual` for Payroc.
- `cost` (string, optional) — Amount in dollars as a string.

### ICPlus

- `rate_bps` (integer, optional) — Rate in basis points (e.g. 200 for 2.00%).
- `amex_rate_bps` (integer, optional) — Amount in basis points for American Express.
- `per_item` (double, optional, nullable) — Amount in dollars per transaction.
- `passthrough_interchange` (string, optional) — Interchange passthrough method (e.g., gross).

### SwipeNonSwipe

- `swipe_per_item` (double, optional) — Amount in dollars (e.g. 0.05 for $0.05).
- `swipe_rate_bps` (double, optional) — Amount in basis points (e.g. 200 for 2.00%).
- `non_swipe_per_item` (double, optional) — Amount in dollars.
- `non_swipe_rate_bps` (double, optional) — Amount in basis points.

### MerchantSurchargeProgram

- `per_item` (double, optional) — Amount in dollars (e.g. 0.05 for $0.05).

### FlatRate

- `per_item` (double, optional) — Amount in dollars (e.g. 0.05 for $0.05).
- `rate_bps` (double, optional) — Amount in basis points (e.g. 200 for 2.00%).

### ProductFee

- `fee_id` (string, optional) — Product fee identifier.
- `cost` (double, optional, nullable) — Amount in dollars. Can be null for some fees.

## Examples

**Request**

```json
{
  "dba_name": "string",
  "platform": "payroc",
  "rep_code": "REP123",
  "signer_email": "string",
  "signer_first_name": "string",
  "signer_last_name": "string",
  "signer_ownership_pct": 1.1
}
```

**Response**

```json
{}
```

**SDK Code**

```python
import requests

url = "https://apps.runpayments.io/ords/relay/api/boarding/v1/merchants/1"

payload = {
    "dba_name": "string",
    "platform": "payroc",
    "rep_code": "REP123",
    "signer_email": "string",
    "signer_first_name": "string",
    "signer_last_name": "string",
    "signer_ownership_pct": 1.1
}
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.put(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://apps.runpayments.io/ords/relay/api/boarding/v1/merchants/1';
const options = {
  method: 'PUT',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"dba_name":"string","platform":"payroc","rep_code":"REP123","signer_email":"string","signer_first_name":"string","signer_last_name":"string","signer_ownership_pct":1.1}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://apps.runpayments.io/ords/relay/api/boarding/v1/merchants/1"

	payload := strings.NewReader("{\n  \"dba_name\": \"string\",\n  \"platform\": \"payroc\",\n  \"rep_code\": \"REP123\",\n  \"signer_email\": \"string\",\n  \"signer_first_name\": \"string\",\n  \"signer_last_name\": \"string\",\n  \"signer_ownership_pct\": 1.1\n}")

	req, _ := http.NewRequest("PUT", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://apps.runpayments.io/ords/relay/api/boarding/v1/merchants/1")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Put.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"dba_name\": \"string\",\n  \"platform\": \"payroc\",\n  \"rep_code\": \"REP123\",\n  \"signer_email\": \"string\",\n  \"signer_first_name\": \"string\",\n  \"signer_last_name\": \"string\",\n  \"signer_ownership_pct\": 1.1\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.put("https://apps.runpayments.io/ords/relay/api/boarding/v1/merchants/1")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"dba_name\": \"string\",\n  \"platform\": \"payroc\",\n  \"rep_code\": \"REP123\",\n  \"signer_email\": \"string\",\n  \"signer_first_name\": \"string\",\n  \"signer_last_name\": \"string\",\n  \"signer_ownership_pct\": 1.1\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('PUT', 'https://apps.runpayments.io/ords/relay/api/boarding/v1/merchants/1', [
  'body' => '{
  "dba_name": "string",
  "platform": "payroc",
  "rep_code": "REP123",
  "signer_email": "string",
  "signer_first_name": "string",
  "signer_last_name": "string",
  "signer_ownership_pct": 1.1
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://apps.runpayments.io/ords/relay/api/boarding/v1/merchants/1");
var request = new RestRequest(Method.PUT);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"dba_name\": \"string\",\n  \"platform\": \"payroc\",\n  \"rep_code\": \"REP123\",\n  \"signer_email\": \"string\",\n  \"signer_first_name\": \"string\",\n  \"signer_last_name\": \"string\",\n  \"signer_ownership_pct\": 1.1\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "dba_name": "string",
  "platform": "payroc",
  "rep_code": "REP123",
  "signer_email": "string",
  "signer_first_name": "string",
  "signer_last_name": "string",
  "signer_ownership_pct": 1.1
] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://apps.runpayments.io/ords/relay/api/boarding/v1/merchants/1")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "PUT"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```