> This page is for version V1 (default).
> For other versions, use one of these documentation indexes:
> - V1 (default): https://docs.ottimate.com/v-1/llms.txt

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

# Create a new payments Vendor

POST https://api.ottimate.com/v1/payments/vendor
Content-Type: application/json

Creates an accounting vendor that payments can be sent to.

There is no upsert. Ottimate matches the request against existing vendors in the company on name, ZIP code and street address, and returns `400` naming the existing vendor when it treats one as a duplicate. The response body of a successful create carries only the new vendor's `id`; read the full record back with `GET /v1/payments/vendor/{id}`.

Send an `Idempotency-Key` header so a retried create cannot produce a second vendor.

Reference: https://docs.ottimate.com/api-reference/api-reference/payments/post-payments-vendor

## Authentication

- `Authorization` header (bearer token, required) — OAuth2 authentication flows. Auth server URLs will vary by environment

## Servers

- `https://api.ottimate.com/v1` (Production, default)
- `https://sandbox-api.ottimate.com/v1` (Sandbox)

## Request

### Headers

- `X-Api-Key` (string, required) — API key for authentication
- `X-API-Version` (string, optional) — API version to use (optional, defaults to latest). Supported values: 1.0.0, 1.1.0.
- `Idempotency-Key` (string, optional) — Client-generated unique key (UUID/ULID recommended). JSON requests: the first 2xx response is cached for 24h and replayed on a same-key retry with a matching body; a different body returns 422. Non-JSON requests (e.g. file uploads): the key is single-use — any same-key retry returns 422 regardless of body. See [Idempotency](https://docs.ottimate.com/idempotency) for full details.

### Body (application/json)

This endpoint expects an object.

- `ottimate_company_id` (string, required) — The Ottimate company ID to create this vendor in, as a numeric string (digits only). Your API user must have access to the company, or the request returns `401`.
- `name` (string, required) — The vendor's business name.
- `erp_vendor_id` (string, required) — The vendor's unique identifier in your ERP system.
- `email` (string, required) — The vendor's primary email address.
- `phone_number` (string, required) — The vendor's primary phone number.
- `address_line_1` (string, required) — The first line of the vendor's mailing address.
- `city` (string, required) — The city of the vendor's mailing address.
- `state` (string, required) — The two-letter state code of the vendor's mailing address.
- `zipcode` (string, required) — The ZIP code of the vendor's mailing address.
- `customer_account_number` (string, optional, nullable) — Your account number with the vendor.
- `invite_electronic_payments` (boolean, optional, nullable) — Whether Ottimate should invite this vendor to enroll in electronic payments.
- `estimated_monthly_volume` (integer, optional, nullable) — Estimated monthly payment volume to this vendor in dollars.
- `contact_name` (string, optional, nullable) — The vendor's primary contact name.
- `address_line_2` (string, optional) — The second line of the vendor's mailing address.
- `country` (string, optional, nullable) — The two-letter ISO country code of the vendor's mailing address.
- `care_of` (string, optional, nullable) — The care-of name for the vendor's mailing address.
- `admin_email` (string, optional) — The email address of the vendor's admin contact.
- `admin_phone` (string, optional) — The phone number of the vendor's admin contact.
- `admin_name` (string, optional) — The name of the vendor's admin contact.
- `metadata` (PaymentsVendorPostRequestBodyContentApplicationJsonSchemaMetadata, optional) — Arbitrary key-value metadata to store on the vendor. Returned unchanged by `GET /v1/payments/vendor/{id}`.

## Response

### 201

Vendor created

- `vendor` (PaymentsVendorPostResponsesContentApplicationJsonSchemaVendor, required)

## Errors

### 400 Bad Request Error

Bad request - Invalid parameters or request format

- `code` (string, required) — Machine-readable error code: an app-specific prefix (e.g. 'INV' for invoices, 'RCPT' for receipts, 'CAT' for catalog) followed by a 4-digit code, e.g. INV4000 for a generic 4xx (validation, not found, etc).
- `message` (ErrorResponseMessage, required, nullable) — Additional error details, can be an object, a string, or null.
- `request_id` (string, optional) — Unique identifier for the request
- `timestamp` (string, optional) — Request timestamp in API Gateway's log format (not ISO 8601).

### 401 Unauthorized Error

Unauthorized - Authentication required or invalid credentials

- `code` (string, required) — Machine-readable error code: an app-specific prefix (e.g. 'INV' for invoices, 'RCPT' for receipts, 'CAT' for catalog) followed by a 4-digit code, e.g. INV4000 for a generic 4xx (validation, not found, etc).
- `message` (ErrorResponseMessage, required, nullable) — Additional error details, can be an object, a string, or null.
- `request_id` (string, optional) — Unique identifier for the request
- `timestamp` (string, optional) — Request timestamp in API Gateway's log format (not ISO 8601).

### 403 Forbidden Error

Forbidden - Access denied or insufficient permissions

- `Post_payments_vendorRequestForbiddenError`
  - ErrorResponse
  - GatewayForbiddenResponse

### 422 Unprocessable Entity Error

Unprocessable entity - Request validation failed

- `code` (string, required) — Machine-readable error code: an app-specific prefix (e.g. 'INV' for invoices, 'RCPT' for receipts, 'CAT' for catalog) followed by a 4-digit code, e.g. INV4000 for a generic 4xx (validation, not found, etc).
- `message` (ErrorResponseMessage, required, nullable) — Additional error details, can be an object, a string, or null.
- `request_id` (string, optional) — Unique identifier for the request
- `timestamp` (string, optional) — Request timestamp in API Gateway's log format (not ISO 8601).

## Types

### PaymentsVendorPostRequestBodyContentApplicationJsonSchemaMetadata

Arbitrary key-value metadata to store on the vendor. Returned unchanged by `GET /v1/payments/vendor/{id}`.

### PaymentsVendorPostResponsesContentApplicationJsonSchemaVendor

- `id` (string, required) — The unique identifier of the newly created vendor.

### ErrorResponseMessage

Additional error details, can be an object, a string, or null.

- map from string to any
- string

### ErrorResponse

- `code` (string, required) — Machine-readable error code: an app-specific prefix (e.g. 'INV' for invoices, 'RCPT' for receipts, 'CAT' for catalog) followed by a 4-digit code, e.g. INV4000 for a generic 4xx (validation, not found, etc).
- `message` (ErrorResponseMessage, required, nullable) — Additional error details, can be an object, a string, or null.
- `request_id` (string, optional) — Unique identifier for the request
- `timestamp` (string, optional) — Request timestamp in API Gateway's log format (not ISO 8601).

### GatewayForbiddenResponse

Bare API Gateway rejection (e.g. missing/invalid X-Api-Key), distinct from the app-level ErrorResponse envelope.

- `message` (string, required)

## Examples

**Request**

```json
{
  "ottimate_company_id": "1234",
  "name": "Example Vendor",
  "erp_vendor_id": "EXAMPLE-VENDOR-1",
  "email": "vendor@example.com",
  "phone_number": "+1 (999) 888-7777",
  "address_line_1": "123 Test St.",
  "city": "Test Town",
  "state": "NY",
  "zipcode": "55555",
  "customer_account_number": "ACCT-0001",
  "invite_electronic_payments": true,
  "estimated_monthly_volume": 1000,
  "contact_name": "Example",
  "address_line_2": "Suite 1",
  "country": "US",
  "care_of": "Example",
  "admin_email": "admin.email@example.com",
  "admin_phone": "+1 (999) 888-7777",
  "admin_name": "Admin Name"
}
```

**Response**

```json
{
  "vendor": {
    "id": "1234"
  }
}
```

**SDK Code**

```python
import requests

url = "https://api.ottimate.com/v1/payments/vendor"

payload = {
    "ottimate_company_id": "1234",
    "name": "Example Vendor",
    "erp_vendor_id": "EXAMPLE-VENDOR-1",
    "email": "vendor@example.com",
    "phone_number": "+1 (999) 888-7777",
    "address_line_1": "123 Test St.",
    "city": "Test Town",
    "state": "NY",
    "zipcode": "55555",
    "customer_account_number": "ACCT-0001",
    "invite_electronic_payments": True,
    "estimated_monthly_volume": 1000,
    "contact_name": "Example",
    "address_line_2": "Suite 1",
    "country": "US",
    "care_of": "Example",
    "admin_email": "admin.email@example.com",
    "admin_phone": "+1 (999) 888-7777",
    "admin_name": "Admin Name"
}
headers = {
    "X-Api-Key": "your-api-key-here",
    "X-API-Version": "1.0.0",
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

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

print(response.json())
```

```javascript
const url = 'https://api.ottimate.com/v1/payments/vendor';
const options = {
  method: 'POST',
  headers: {
    'X-Api-Key': 'your-api-key-here',
    'X-API-Version': '1.0.0',
    Authorization: 'Bearer <token>',
    'Content-Type': 'application/json'
  },
  body: '{"ottimate_company_id":"1234","name":"Example Vendor","erp_vendor_id":"EXAMPLE-VENDOR-1","email":"vendor@example.com","phone_number":"+1 (999) 888-7777","address_line_1":"123 Test St.","city":"Test Town","state":"NY","zipcode":"55555","customer_account_number":"ACCT-0001","invite_electronic_payments":true,"estimated_monthly_volume":1000,"contact_name":"Example","address_line_2":"Suite 1","country":"US","care_of":"Example","admin_email":"admin.email@example.com","admin_phone":"+1 (999) 888-7777","admin_name":"Admin Name"}'
};

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://api.ottimate.com/v1/payments/vendor"

	payload := strings.NewReader("{\n  \"ottimate_company_id\": \"1234\",\n  \"name\": \"Example Vendor\",\n  \"erp_vendor_id\": \"EXAMPLE-VENDOR-1\",\n  \"email\": \"vendor@example.com\",\n  \"phone_number\": \"+1 (999) 888-7777\",\n  \"address_line_1\": \"123 Test St.\",\n  \"city\": \"Test Town\",\n  \"state\": \"NY\",\n  \"zipcode\": \"55555\",\n  \"customer_account_number\": \"ACCT-0001\",\n  \"invite_electronic_payments\": true,\n  \"estimated_monthly_volume\": 1000,\n  \"contact_name\": \"Example\",\n  \"address_line_2\": \"Suite 1\",\n  \"country\": \"US\",\n  \"care_of\": \"Example\",\n  \"admin_email\": \"admin.email@example.com\",\n  \"admin_phone\": \"+1 (999) 888-7777\",\n  \"admin_name\": \"Admin Name\"\n}")

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

	req.Header.Add("X-Api-Key", "your-api-key-here")
	req.Header.Add("X-API-Version", "1.0.0")
	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://api.ottimate.com/v1/payments/vendor")

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

request = Net::HTTP::Post.new(url)
request["X-Api-Key"] = 'your-api-key-here'
request["X-API-Version"] = '1.0.0'
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"ottimate_company_id\": \"1234\",\n  \"name\": \"Example Vendor\",\n  \"erp_vendor_id\": \"EXAMPLE-VENDOR-1\",\n  \"email\": \"vendor@example.com\",\n  \"phone_number\": \"+1 (999) 888-7777\",\n  \"address_line_1\": \"123 Test St.\",\n  \"city\": \"Test Town\",\n  \"state\": \"NY\",\n  \"zipcode\": \"55555\",\n  \"customer_account_number\": \"ACCT-0001\",\n  \"invite_electronic_payments\": true,\n  \"estimated_monthly_volume\": 1000,\n  \"contact_name\": \"Example\",\n  \"address_line_2\": \"Suite 1\",\n  \"country\": \"US\",\n  \"care_of\": \"Example\",\n  \"admin_email\": \"admin.email@example.com\",\n  \"admin_phone\": \"+1 (999) 888-7777\",\n  \"admin_name\": \"Admin Name\"\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://api.ottimate.com/v1/payments/vendor")
  .header("X-Api-Key", "your-api-key-here")
  .header("X-API-Version", "1.0.0")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"ottimate_company_id\": \"1234\",\n  \"name\": \"Example Vendor\",\n  \"erp_vendor_id\": \"EXAMPLE-VENDOR-1\",\n  \"email\": \"vendor@example.com\",\n  \"phone_number\": \"+1 (999) 888-7777\",\n  \"address_line_1\": \"123 Test St.\",\n  \"city\": \"Test Town\",\n  \"state\": \"NY\",\n  \"zipcode\": \"55555\",\n  \"customer_account_number\": \"ACCT-0001\",\n  \"invite_electronic_payments\": true,\n  \"estimated_monthly_volume\": 1000,\n  \"contact_name\": \"Example\",\n  \"address_line_2\": \"Suite 1\",\n  \"country\": \"US\",\n  \"care_of\": \"Example\",\n  \"admin_email\": \"admin.email@example.com\",\n  \"admin_phone\": \"+1 (999) 888-7777\",\n  \"admin_name\": \"Admin Name\"\n}")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.ottimate.com/v1/payments/vendor', [
  'body' => '{
  "ottimate_company_id": "1234",
  "name": "Example Vendor",
  "erp_vendor_id": "EXAMPLE-VENDOR-1",
  "email": "vendor@example.com",
  "phone_number": "+1 (999) 888-7777",
  "address_line_1": "123 Test St.",
  "city": "Test Town",
  "state": "NY",
  "zipcode": "55555",
  "customer_account_number": "ACCT-0001",
  "invite_electronic_payments": true,
  "estimated_monthly_volume": 1000,
  "contact_name": "Example",
  "address_line_2": "Suite 1",
  "country": "US",
  "care_of": "Example",
  "admin_email": "admin.email@example.com",
  "admin_phone": "+1 (999) 888-7777",
  "admin_name": "Admin Name"
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
    'X-API-Version' => '1.0.0',
    'X-Api-Key' => 'your-api-key-here',
  ],
]);

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

```csharp
using RestSharp;

var client = new RestClient("https://api.ottimate.com/v1/payments/vendor");
var request = new RestRequest(Method.POST);
request.AddHeader("X-Api-Key", "your-api-key-here");
request.AddHeader("X-API-Version", "1.0.0");
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"ottimate_company_id\": \"1234\",\n  \"name\": \"Example Vendor\",\n  \"erp_vendor_id\": \"EXAMPLE-VENDOR-1\",\n  \"email\": \"vendor@example.com\",\n  \"phone_number\": \"+1 (999) 888-7777\",\n  \"address_line_1\": \"123 Test St.\",\n  \"city\": \"Test Town\",\n  \"state\": \"NY\",\n  \"zipcode\": \"55555\",\n  \"customer_account_number\": \"ACCT-0001\",\n  \"invite_electronic_payments\": true,\n  \"estimated_monthly_volume\": 1000,\n  \"contact_name\": \"Example\",\n  \"address_line_2\": \"Suite 1\",\n  \"country\": \"US\",\n  \"care_of\": \"Example\",\n  \"admin_email\": \"admin.email@example.com\",\n  \"admin_phone\": \"+1 (999) 888-7777\",\n  \"admin_name\": \"Admin Name\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "X-Api-Key": "your-api-key-here",
  "X-API-Version": "1.0.0",
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = [
  "ottimate_company_id": "1234",
  "name": "Example Vendor",
  "erp_vendor_id": "EXAMPLE-VENDOR-1",
  "email": "vendor@example.com",
  "phone_number": "+1 (999) 888-7777",
  "address_line_1": "123 Test St.",
  "city": "Test Town",
  "state": "NY",
  "zipcode": "55555",
  "customer_account_number": "ACCT-0001",
  "invite_electronic_payments": true,
  "estimated_monthly_volume": 1000,
  "contact_name": "Example",
  "address_line_2": "Suite 1",
  "country": "US",
  "care_of": "Example",
  "admin_email": "admin.email@example.com",
  "admin_phone": "+1 (999) 888-7777",
  "admin_name": "Admin Name"
] as [String : Any]

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

let request = NSMutableURLRequest(url: NSURL(string: "https://api.ottimate.com/v1/payments/vendor")! 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()
```