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

# Create a new merchant

POST https://apps.runpayments.io/ords/relay/api/boarding/v1/merchants
Content-Type: application/json

Create a new merchant in Run Partner. A successful request returns a `201` status with a `merchant_id` that can be used in subsequent API calls to retrieve updated merchant data.

Validation notes:
- `in_person_pct` + `online_pct` + `telephone_pct` must sum to 100 when provided.
- `tax_id`, when provided, must be a 9-digit number (dashes allowed).
- Phone numbers, when provided, must be 10 digits in the format `###-###-####`.
- The `platform` must match the platform of the supplied `rep_code`.
- The sum of `signer_ownership_pct` and all `owners[].ownership_pct` values must not exceed 100.


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

## Authentication

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

## Request

### Body (application/json)

This endpoint expects a MerchantApplication.

- `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.
- `dba_name` (string, required) — Doing Business As (DBA) name.
- `signer_first_name` (string, required) — First name of the signer.
- `signer_last_name` (string, required) — Last name of the signer.
- `signer_email` (string, required) — Email address 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.
- `customer_id` (double, optional) — Used if adding to an existing account.
- `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.
- `legal_name` (string, optional) — Legal name of the business.
- `tax_id` (string, optional) — Tax identification number. Must be a 9-digit number (dashes allowed).
- `years_in_business` (double, optional) — Number of years the business has been operating.
- `website` (string, optional) — Business website URL.
- `phone` (string, optional) — Phone number in the format `###-###-####`.
- `mcc_code` (string, optional) — Merchant Category Code (MCC). See /mcc for valid values. Ignored if `application_template_id` is provided.
- `business_desc` (string, optional) — Description of the business.
- `when_card_charged` (enum, optional) — When the card is charged.
  - Allowed values: `in_advance`, `on_delivery`
- `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`
- `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.
- `annual_volume` (double, optional) — Annual transaction volume in dollars.
- `average_ticket` (double, optional) — Average transaction amount in dollars.
- `in_person_pct` (double, optional) — Percentage of in-person transactions. Must sum to 100 with `online_pct` and `telephone_pct`.
- `online_pct` (double, optional) — Percentage of online transactions. Must sum to 100 with `in_person_pct` and `telephone_pct`.
- `telephone_pct` (double, optional) — Percentage of telephone transactions. Must sum to 100 with `in_person_pct` and `online_pct`.
- `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`
- `signer_dob` (string, optional) — Date of birth of the signer in the format mm/dd/yyyy.
- `signer_ssn` (string, optional) — Social Security number of the signer.
- `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_phone` (string, optional) — Phone number in the format `###-###-####`.
- `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.
- `addresses` (list of Address, optional) — List of addresses associated with the merchant.
- `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.
- `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.
- `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.
- `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.
- `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.
- `is_test` (boolean, optional) — If true, the merchant is created as a test record.

## Response

### 201

Merchant created successfully.

- `merchant_id` (string, optional, nullable) — Unique identifier for the created merchant. Null if the request failed.
- `error_message` (string, optional, nullable) — Description of the validation failure. Null if the request succeeded.

## Errors

### 400 Bad Request Error

Bad request. `merchant_id` is null and `error_message` describes the validation failure.

- `merchant_id` (string, optional, nullable) — Unique identifier for the created merchant. Null if the request failed.
- `error_message` (string, optional, nullable) — Description of the validation failure. Null if the request succeeded.

### 401 Unauthorized Error

Unauthorized.

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

## Types

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

### 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`

### 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`.

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

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

### 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%).

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

### ProductFee

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

## Examples

**Request**

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

**Response**

```json
{
  "merchant_id": "string",
  "error_message": "string"
}
```

**SDK Code**

```python
import requests

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

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

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

print(response.json())
```

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

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

	req, _ := http.NewRequest("POST", 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")

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

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"platform\": \"payroc\",\n  \"rep_code\": \"REP123\",\n  \"dba_name\": \"string\",\n  \"signer_first_name\": \"string\",\n  \"signer_last_name\": \"string\",\n  \"signer_email\": \"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.post("https://apps.runpayments.io/ords/relay/api/boarding/v1/merchants")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"platform\": \"payroc\",\n  \"rep_code\": \"REP123\",\n  \"dba_name\": \"string\",\n  \"signer_first_name\": \"string\",\n  \"signer_last_name\": \"string\",\n  \"signer_email\": \"string\",\n  \"signer_ownership_pct\": 1.1\n}")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://apps.runpayments.io/ords/relay/api/boarding/v1/merchants', [
  'body' => '{
  "platform": "payroc",
  "rep_code": "REP123",
  "dba_name": "string",
  "signer_first_name": "string",
  "signer_last_name": "string",
  "signer_email": "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");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"platform\": \"payroc\",\n  \"rep_code\": \"REP123\",\n  \"dba_name\": \"string\",\n  \"signer_first_name\": \"string\",\n  \"signer_last_name\": \"string\",\n  \"signer_email\": \"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 = [
  "platform": "payroc",
  "rep_code": "REP123",
  "dba_name": "string",
  "signer_first_name": "string",
  "signer_last_name": "string",
  "signer_email": "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")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
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()
```