curl --request POST \
--url https://go.aiinsurance.io/api/v1/companies/{companyId}/financials/payees/{payeeId}/merge \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"toPayeeId": "550e8400-e29b-41d4-a716-446655440211"
}
'import requests
url = "https://go.aiinsurance.io/api/v1/companies/{companyId}/financials/payees/{payeeId}/merge"
payload = { "toPayeeId": "550e8400-e29b-41d4-a716-446655440211" }
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({toPayeeId: '550e8400-e29b-41d4-a716-446655440211'})
};
fetch('https://go.aiinsurance.io/api/v1/companies/{companyId}/financials/payees/{payeeId}/merge', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://go.aiinsurance.io/api/v1/companies/{companyId}/financials/payees/{payeeId}/merge",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'toPayeeId' => '550e8400-e29b-41d4-a716-446655440211'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://go.aiinsurance.io/api/v1/companies/{companyId}/financials/payees/{payeeId}/merge"
payload := strings.NewReader("{\n \"toPayeeId\": \"550e8400-e29b-41d4-a716-446655440211\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<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))
}HttpResponse<String> response = Unirest.post("https://go.aiinsurance.io/api/v1/companies/{companyId}/financials/payees/{payeeId}/merge")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"toPayeeId\": \"550e8400-e29b-41d4-a716-446655440211\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://go.aiinsurance.io/api/v1/companies/{companyId}/financials/payees/{payeeId}/merge")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"toPayeeId\": \"550e8400-e29b-41d4-a716-446655440211\"\n}"
response = http.request(request)
puts response.read_body{
"journalIds": [
"6d8e0f2a-4b5c-4d7e-9f1a-0b2c3d4e5f6a",
"7e9f1a3b-5c6d-4e8f-0a2b-1c3d4e5f6a7b",
"8f0a2b4c-6d7e-4f9a-1b3c-2d4e5f6a7b8c"
]
}Merge Payee
Repoints every non-deleted invoice linked to {payeeId} at toPayeeId,
in ONE transaction — the merge composition. Per linked invoice:
payment_removed ×k → payee_changed → payment_recorded ×k (invoices
without live payments take just the middle step). Re-recorded marks
copy amount / date / memo / line item / erode flag verbatim under NEW
server-minted payment ids — EXCEPT payments whose removal composed a
reserve unwind (reset-absorbed erosion), which re-record NON-eroding so
reserves are not eroded twice.
Idempotent by convergence. All member actions are server-derived (no
client actionIds, no If-Match): a retry finds nothing linked to the
merged payee and emits nothing (journalIds: []).
Selector vs target. {payeeId} is a pure selector — an id with no
linked invoices converges to an empty merge; toPayeeId must exist
(422 LINK_TARGET_MISSING) and must differ from {payeeId} (a
schema-level 400).
Required permission: payee.merge
curl --request POST \
--url https://go.aiinsurance.io/api/v1/companies/{companyId}/financials/payees/{payeeId}/merge \
--header 'Authorization: <api-key>' \
--header 'Content-Type: application/json' \
--data '
{
"toPayeeId": "550e8400-e29b-41d4-a716-446655440211"
}
'import requests
url = "https://go.aiinsurance.io/api/v1/companies/{companyId}/financials/payees/{payeeId}/merge"
payload = { "toPayeeId": "550e8400-e29b-41d4-a716-446655440211" }
headers = {
"Authorization": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({toPayeeId: '550e8400-e29b-41d4-a716-446655440211'})
};
fetch('https://go.aiinsurance.io/api/v1/companies/{companyId}/financials/payees/{payeeId}/merge', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://go.aiinsurance.io/api/v1/companies/{companyId}/financials/payees/{payeeId}/merge",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'toPayeeId' => '550e8400-e29b-41d4-a716-446655440211'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <api-key>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://go.aiinsurance.io/api/v1/companies/{companyId}/financials/payees/{payeeId}/merge"
payload := strings.NewReader("{\n \"toPayeeId\": \"550e8400-e29b-41d4-a716-446655440211\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<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))
}HttpResponse<String> response = Unirest.post("https://go.aiinsurance.io/api/v1/companies/{companyId}/financials/payees/{payeeId}/merge")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"toPayeeId\": \"550e8400-e29b-41d4-a716-446655440211\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://go.aiinsurance.io/api/v1/companies/{companyId}/financials/payees/{payeeId}/merge")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"toPayeeId\": \"550e8400-e29b-41d4-a716-446655440211\"\n}"
response = http.request(request)
puts response.read_body{
"journalIds": [
"6d8e0f2a-4b5c-4d7e-9f1a-0b2c3d4e5f6a",
"7e9f1a3b-5c6d-4e8f-0a2b-1c3d4e5f6a7b",
"8f0a2b4c-6d7e-4f9a-1b3c-2d4e5f6a7b8c"
]
}Authorizations
API key authentication. Send your raw API key as the Authorization header value with NO scheme prefix — Authorization: YOUR-API-KEY. Do NOT prefix it with Bearer or ApiKey, and do not use an X-API-Key header; those are not accepted.
Path Parameters
Company identifier
The payee being merged AWAY — a pure selector; every invoice linked to it is repointed
Body
The surviving payee every linked invoice is repointed to; must exist and differ from {payeeId}
Optional display label for the source system's author (e.g. the integrator-side user). Stamped as the journal record's display attribution; the acting principal stays the External API service user, so a label can never impersonate an in-app user. Ignored on idempotent replays
1 - 255Response
Every emitted journal id, in execution order — empty on a converged retry (nothing left linked to the merged payee)
Every emitted journal id, in execution order
