Replace beneficial owners
Replaces the business’s entire set of beneficial owners. Entries carrying an id are updated, entries without one are created, and any person the payload omits is deleted.
Replace rather than patch because ownership percentages are only meaningful as a set: the currency provider validates their total, so a partial update has no coherent meaning. Read the current set first, modify it, and send it back whole.
Recording an fx-account-holder is what unblocks international-fx accounts. Check GET /limitations afterwards to confirm nothing else is outstanding.
const options = {
method: 'PUT',
headers: {'api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
data: [
{
firstName: 'Dana',
lastName: 'Okonjo',
dateOfBirth: '1984-03-11',
address: {
line1: '500 Congress Ave',
city: 'Austin',
state: 'TX',
postalCode: '78701',
countryCode: 'US'
},
usResident: true,
ownershipPercentage: 0.6,
jobTitle: 'chief-executive-officer',
taxInfo: {type: 'ssn', identifier: '123-45-6789'},
types: ['ubo', 'director', 'fx-account-holder'],
email: '[email protected]'
}
]
})
};
fetch('https://api.melio.com/v2/entities/{entityId}/beneficial-owners', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.melio.com/v2/entities/{entityId}/beneficial-owners"
payload = { "data": [
{
"firstName": "Dana",
"lastName": "Okonjo",
"dateOfBirth": "1984-03-11",
"address": {
"line1": "500 Congress Ave",
"city": "Austin",
"state": "TX",
"postalCode": "78701",
"countryCode": "US"
},
"usResident": True,
"ownershipPercentage": 0.6,
"jobTitle": "chief-executive-officer",
"taxInfo": {
"type": "ssn",
"identifier": "123-45-6789"
},
"types": ["ubo", "director", "fx-account-holder"],
"email": "[email protected]"
}
] }
headers = {
"api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)curl --request PUT \
--url https://api.melio.com/v2/entities/{entityId}/beneficial-owners \
--header 'Content-Type: application/json' \
--header 'api-key: <api-key>' \
--data '
{
"data": [
{
"firstName": "Dana",
"lastName": "Okonjo",
"dateOfBirth": "1984-03-11",
"address": {
"line1": "500 Congress Ave",
"city": "Austin",
"state": "TX",
"postalCode": "78701",
"countryCode": "US"
},
"usResident": true,
"ownershipPercentage": 0.6,
"jobTitle": "chief-executive-officer",
"taxInfo": {
"type": "ssn",
"identifier": "123-45-6789"
},
"types": [
"ubo",
"director",
"fx-account-holder"
],
"email": "[email protected]"
}
]
}
'HttpResponse<String> response = Unirest.put("https://api.melio.com/v2/entities/{entityId}/beneficial-owners")
.header("api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"data\": [\n {\n \"firstName\": \"Dana\",\n \"lastName\": \"Okonjo\",\n \"dateOfBirth\": \"1984-03-11\",\n \"address\": {\n \"line1\": \"500 Congress Ave\",\n \"city\": \"Austin\",\n \"state\": \"TX\",\n \"postalCode\": \"78701\",\n \"countryCode\": \"US\"\n },\n \"usResident\": true,\n \"ownershipPercentage\": 0.6,\n \"jobTitle\": \"chief-executive-officer\",\n \"taxInfo\": {\n \"type\": \"ssn\",\n \"identifier\": \"123-45-6789\"\n },\n \"types\": [\n \"ubo\",\n \"director\",\n \"fx-account-holder\"\n ],\n \"email\": \"[email protected]\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.melio.com/v2/entities/{entityId}/beneficial-owners")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"data\": [\n {\n \"firstName\": \"Dana\",\n \"lastName\": \"Okonjo\",\n \"dateOfBirth\": \"1984-03-11\",\n \"address\": {\n \"line1\": \"500 Congress Ave\",\n \"city\": \"Austin\",\n \"state\": \"TX\",\n \"postalCode\": \"78701\",\n \"countryCode\": \"US\"\n },\n \"usResident\": true,\n \"ownershipPercentage\": 0.6,\n \"jobTitle\": \"chief-executive-officer\",\n \"taxInfo\": {\n \"type\": \"ssn\",\n \"identifier\": \"123-45-6789\"\n },\n \"types\": [\n \"ubo\",\n \"director\",\n \"fx-account-holder\"\n ],\n \"email\": \"[email protected]\"\n }\n ]\n}"
response = http.request(request)
puts response.read_bodypackage main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.melio.com/v2/entities/{entityId}/beneficial-owners"
payload := strings.NewReader("{\n \"data\": [\n {\n \"firstName\": \"Dana\",\n \"lastName\": \"Okonjo\",\n \"dateOfBirth\": \"1984-03-11\",\n \"address\": {\n \"line1\": \"500 Congress Ave\",\n \"city\": \"Austin\",\n \"state\": \"TX\",\n \"postalCode\": \"78701\",\n \"countryCode\": \"US\"\n },\n \"usResident\": true,\n \"ownershipPercentage\": 0.6,\n \"jobTitle\": \"chief-executive-officer\",\n \"taxInfo\": {\n \"type\": \"ssn\",\n \"identifier\": \"123-45-6789\"\n },\n \"types\": [\n \"ubo\",\n \"director\",\n \"fx-account-holder\"\n ],\n \"email\": \"[email protected]\"\n }\n ]\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"data": [
{
"id": 123,
"firstName": "<string>",
"lastName": "<string>",
"dateOfBirth": "2023-12-25",
"address": {
"line1": "<string>",
"city": "<string>",
"postalCode": "<string>",
"countryCode": "<string>",
"line2": "<string>",
"state": "<string>"
},
"usResident": true,
"hasIdentityDocument": true,
"types": [
"ubo"
],
"ownershipPercentage": 123,
"jobTitle": "chief-executive-officer",
"taxInfo": {
"type": "ssn",
"identifierLast4": "<string>"
},
"internationalIdType": "passport",
"internationalId": "<string>",
"email": "<string>",
"phoneNumber": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z"
}
]
}{
"error": {
"type": "invalid_request_error",
"code": "VALIDATION_ERROR",
"message": "<string>",
"details": {}
}
}{
"error": {
"type": "invalid_request_error",
"code": "VALIDATION_ERROR",
"message": "<string>",
"details": {}
}
}Authorizations
Path Parameters
Body
Hide child attributes
Hide child attributes
22The person's home address. Unlike a counterparty address this may be in the US — send countryCode: US for a US resident.
Hide child attributes
Hide child attributes
Street address. Must be a real street address, not a PO box.
Two-letter ISO 3166-1 alpha-2 country code.
^[A-Za-z]{2}$State, province or region. Optional — send an empty string where the country has none.
1The role a person holds in the business. ubo is an ultimate beneficial owner (someone with a material ownership stake), director is a control person, and fx-account-holder is the individual who acts for the business towards the currency provider. One person may hold several roles; exactly one person must be the fx-account-holder.
ubo, director, fx-account-holder The id of an existing person to update. Omit to create.
Share of the business held, as a decimal (0.25 = 25%). Required for anyone whose types include ubo. The currency provider validates the total across all ubo entries, so send the complete set in one request.
0 <= x <= 1chief-executive-officer, chief-financial-officer, managing-member, general-partner, president, vice-president, treasurer Required when usResident is false.
passport, driver-license, national-id Required when usResident is false.
A scan or photo of this person's government-issued ID, uploaded with POST /attachments.
Optional in general. The FX provider insists on it in exactly two cases, and the request is rejected with 400 VALIDATION_ERROR naming the person if it is absent: when usResident is false, or for every beneficial owner when the entity's businessType is sole-proprietorship — including US residents.
Only the front is required. The provider's guidance asks for both sides of a driver's licence or national ID, but nothing downstream reads the back, so a front-only upload is accepted here exactly as it is elsewhere in Melio. Send backAttachmentId when you have it.
Write-only: BeneficialOwner reports hasIdentityDocument and never a reference to the file.
Response
The business's beneficial owners after the replacement.
Hide child attributes
Hide child attributes
A counterparty address outside the US. Unlike Address, state is free-form (most countries have no state; send an empty string or omit it) and postalCode is not a US ZIP. countryCode is required and must not be US — a US-domiciled counterparty belongs on a domestic account type.
Hide child attributes
Hide child attributes
Street address. Must be a real street address, not a PO box.
Two-letter ISO 3166-1 alpha-2 country code.
^[A-Za-z]{2}$State, province or region. Optional — send an empty string where the country has none.
Whether a government ID is on file for this person. The document itself cannot be read back through this API.
The role a person holds in the business. ubo is an ultimate beneficial owner (someone with a material ownership stake), director is a control person, and fx-account-holder is the individual who acts for the business towards the currency provider. One person may hold several roles; exactly one person must be the fx-account-holder.
ubo, director, fx-account-holder Decimal share (0.25 = 25%)
chief-executive-officer, chief-financial-officer, managing-member, general-partner, president, vice-president, treasurer passport, driver-license, national-id Last four characters of the identifier on file
const options = {
method: 'PUT',
headers: {'api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
data: [
{
firstName: 'Dana',
lastName: 'Okonjo',
dateOfBirth: '1984-03-11',
address: {
line1: '500 Congress Ave',
city: 'Austin',
state: 'TX',
postalCode: '78701',
countryCode: 'US'
},
usResident: true,
ownershipPercentage: 0.6,
jobTitle: 'chief-executive-officer',
taxInfo: {type: 'ssn', identifier: '123-45-6789'},
types: ['ubo', 'director', 'fx-account-holder'],
email: '[email protected]'
}
]
})
};
fetch('https://api.melio.com/v2/entities/{entityId}/beneficial-owners', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.melio.com/v2/entities/{entityId}/beneficial-owners"
payload = { "data": [
{
"firstName": "Dana",
"lastName": "Okonjo",
"dateOfBirth": "1984-03-11",
"address": {
"line1": "500 Congress Ave",
"city": "Austin",
"state": "TX",
"postalCode": "78701",
"countryCode": "US"
},
"usResident": True,
"ownershipPercentage": 0.6,
"jobTitle": "chief-executive-officer",
"taxInfo": {
"type": "ssn",
"identifier": "123-45-6789"
},
"types": ["ubo", "director", "fx-account-holder"],
"email": "[email protected]"
}
] }
headers = {
"api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.put(url, json=payload, headers=headers)
print(response.text)curl --request PUT \
--url https://api.melio.com/v2/entities/{entityId}/beneficial-owners \
--header 'Content-Type: application/json' \
--header 'api-key: <api-key>' \
--data '
{
"data": [
{
"firstName": "Dana",
"lastName": "Okonjo",
"dateOfBirth": "1984-03-11",
"address": {
"line1": "500 Congress Ave",
"city": "Austin",
"state": "TX",
"postalCode": "78701",
"countryCode": "US"
},
"usResident": true,
"ownershipPercentage": 0.6,
"jobTitle": "chief-executive-officer",
"taxInfo": {
"type": "ssn",
"identifier": "123-45-6789"
},
"types": [
"ubo",
"director",
"fx-account-holder"
],
"email": "[email protected]"
}
]
}
'HttpResponse<String> response = Unirest.put("https://api.melio.com/v2/entities/{entityId}/beneficial-owners")
.header("api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"data\": [\n {\n \"firstName\": \"Dana\",\n \"lastName\": \"Okonjo\",\n \"dateOfBirth\": \"1984-03-11\",\n \"address\": {\n \"line1\": \"500 Congress Ave\",\n \"city\": \"Austin\",\n \"state\": \"TX\",\n \"postalCode\": \"78701\",\n \"countryCode\": \"US\"\n },\n \"usResident\": true,\n \"ownershipPercentage\": 0.6,\n \"jobTitle\": \"chief-executive-officer\",\n \"taxInfo\": {\n \"type\": \"ssn\",\n \"identifier\": \"123-45-6789\"\n },\n \"types\": [\n \"ubo\",\n \"director\",\n \"fx-account-holder\"\n ],\n \"email\": \"[email protected]\"\n }\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.melio.com/v2/entities/{entityId}/beneficial-owners")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Put.new(url)
request["api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"data\": [\n {\n \"firstName\": \"Dana\",\n \"lastName\": \"Okonjo\",\n \"dateOfBirth\": \"1984-03-11\",\n \"address\": {\n \"line1\": \"500 Congress Ave\",\n \"city\": \"Austin\",\n \"state\": \"TX\",\n \"postalCode\": \"78701\",\n \"countryCode\": \"US\"\n },\n \"usResident\": true,\n \"ownershipPercentage\": 0.6,\n \"jobTitle\": \"chief-executive-officer\",\n \"taxInfo\": {\n \"type\": \"ssn\",\n \"identifier\": \"123-45-6789\"\n },\n \"types\": [\n \"ubo\",\n \"director\",\n \"fx-account-holder\"\n ],\n \"email\": \"[email protected]\"\n }\n ]\n}"
response = http.request(request)
puts response.read_bodypackage main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.melio.com/v2/entities/{entityId}/beneficial-owners"
payload := strings.NewReader("{\n \"data\": [\n {\n \"firstName\": \"Dana\",\n \"lastName\": \"Okonjo\",\n \"dateOfBirth\": \"1984-03-11\",\n \"address\": {\n \"line1\": \"500 Congress Ave\",\n \"city\": \"Austin\",\n \"state\": \"TX\",\n \"postalCode\": \"78701\",\n \"countryCode\": \"US\"\n },\n \"usResident\": true,\n \"ownershipPercentage\": 0.6,\n \"jobTitle\": \"chief-executive-officer\",\n \"taxInfo\": {\n \"type\": \"ssn\",\n \"identifier\": \"123-45-6789\"\n },\n \"types\": [\n \"ubo\",\n \"director\",\n \"fx-account-holder\"\n ],\n \"email\": \"[email protected]\"\n }\n ]\n}")
req, _ := http.NewRequest("PUT", url, payload)
req.Header.Add("api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}{
"data": [
{
"id": 123,
"firstName": "<string>",
"lastName": "<string>",
"dateOfBirth": "2023-12-25",
"address": {
"line1": "<string>",
"city": "<string>",
"postalCode": "<string>",
"countryCode": "<string>",
"line2": "<string>",
"state": "<string>"
},
"usResident": true,
"hasIdentityDocument": true,
"types": [
"ubo"
],
"ownershipPercentage": 123,
"jobTitle": "chief-executive-officer",
"taxInfo": {
"type": "ssn",
"identifierLast4": "<string>"
},
"internationalIdType": "passport",
"internationalId": "<string>",
"email": "<string>",
"phoneNumber": "<string>",
"createdAt": "2023-11-07T05:31:56Z",
"updatedAt": "2023-11-07T05:31:56Z"
}
]
}{
"error": {
"type": "invalid_request_error",
"code": "VALIDATION_ERROR",
"message": "<string>",
"details": {}
}
}{
"error": {
"type": "invalid_request_error",
"code": "VALIDATION_ERROR",
"message": "<string>",
"details": {}
}
}