Request a member genealogy move
Requires a writable opaque member token, a portal JWT or a verified One Auth identity access token for a non-impersonated rep or shopper. A legacy member session JWT that resolves to the current member is read-only and returns 403. A portal JWT minted read-only is refused with 401 on a write, by the legacy authentication these routes also run, as are a root admin portal JWT, an admin portal JWT with no rep membership of its own, and any other non-member credential. Writes share the member API limit of 120 requests per minute per bearer credential, and return 429 beyond it. Requires the bearer member’s current rep eligibility and movement policy. The moved node and destination must remain within the member’s current team; no member or actor selector is accepted. HTTP move admission is disabled unless the company is explicitly included in GENEALOGY_MOVE_COMPANY_IDS after migration prerequisites are satisfied. Return 200 only when applied or unchanged, and 202 with a human approval request or durable full-validation job. Clients cannot request unbounded synchronous execution. No legacy sponsor-axis value is changed by this endpoint. The example uses illustrative fixture IDs. Substitute records visible to your authenticated company or member.
curl -X POST 'https://api.fluid.app/api/member/v2026-10/team/01a08945-0cb7-7748-b66d-358cdca923b6/move' \
-H 'Authorization: Bearer <member-token>' \
-H 'Content-Type: application/json' \
--data \{\"move\":\{\"parent_node_id\":\"01a08945-0cbc-774c-a046-d7be609c4829\"\}\}import requests
url = "https://api.fluid.app/api/member/v2026-10/team/{id}/move"
payload = { "move": { "parent_node_id": "01a08945-0cbc-774c-a046-d7be609c4829" } }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({move: {parent_node_id: '01a08945-0cbc-774c-a046-d7be609c4829'}})
};
fetch('https://api.fluid.app/api/member/v2026-10/team/{id}/move', 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://api.fluid.app/api/member/v2026-10/team/{id}/move",
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([
'move' => [
'parent_node_id' => '01a08945-0cbc-774c-a046-d7be609c4829'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://api.fluid.app/api/member/v2026-10/team/{id}/move"
payload := strings.NewReader("{\n \"move\": {\n \"parent_node_id\": \"01a08945-0cbc-774c-a046-d7be609c4829\"\n }\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(string(body))
}HttpResponse<String> response = Unirest.post("https://api.fluid.app/api/member/v2026-10/team/{id}/move")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"move\": {\n \"parent_node_id\": \"01a08945-0cbc-774c-a046-d7be609c4829\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/member/v2026-10/team/{id}/move")
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 \"move\": {\n \"parent_node_id\": \"01a08945-0cbc-774c-a046-d7be609c4829\"\n }\n}"
response = http.request(request)
puts response.read_body{
"changed": true,
"deferred": false,
"move_job": null,
"move_request": null,
"placement": {
"id": "01a08945-1a42-7048-a497-8bb5c88416ee",
"actor_id": "c0dd6812-0ba6-56d2-879c-a36112f813c2",
"actor_type": "Company::Member",
"effective_at": "2026-09-10T03:03:22.432397Z",
"ended_at": null,
"leg": null,
"member_id": "423f3c52-5440-5955-8e53-e2050d0b86b6",
"node_id": "01a08945-1a27-7dcf-9971-de363f3408ba",
"parent_node_id": "01a08945-1a2c-7fa7-9656-d36495b26b1c",
"reason": null,
"request_id": null,
"source": "rep",
"tree_id": "7096ad49-7117-53f6-8f7f-4805473d14c5"
},
"queued": false,
"status": 200,
"meta": {
"request_uuid": null,
"timestamp": "2026-09-10T03:03:22Z"
}
}{
"changed": false,
"deferred": true,
"move_job": {
"id": "01a08945-1911-7ca5-a402-e9558c7e5fcb",
"approval_request_id": null,
"attempts": 0,
"created_at": "2026-09-10T03:03:22.129487Z",
"failure_details": {},
"failure_type": null,
"finished_at": null,
"leg": null,
"node_id": "01a08945-0cb7-7748-b66d-358cdca923b6",
"parent_node_id": "01a08945-0cbc-774c-a046-d7be609c4829",
"placement_id": null,
"reason": null,
"requested_by_id": "c0dd6812-0ba6-56d2-879c-a36112f813c2",
"requested_by_type": "Company::Member",
"started_at": null,
"status": "pending",
"tree_id": "7096ad49-7117-53f6-8f7f-4805473d14c5"
},
"move_request": null,
"placement": null,
"queued": false,
"status": 202,
"meta": {
"request_uuid": null,
"timestamp": "2026-09-10T03:03:22Z"
}
}{
"message": "<string>",
"error": "<unknown>"
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"error": "Rate limit exceeded",
"message": "Too many requests. Please wait before trying again.",
"retry_after": 30
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}Authorizations
A member credential for the member's own team — a member or customer session JWT, a portal JWT, or a member's user token. It follows the member API's credential rules. Company service tokens, admin credentials and members who can no longer act are refused, and a session JWT cannot write. A member whose user is also an admin of the company may read, but not change, their own team with their own member token, one no admin holds.
Headers
Optional client key that makes the request safe to retry. The first request with a key is evaluated and its outcome recorded; a retry with the same key and the same proposal replays that outcome, with the resource's current state, instead of moving again. The same key with a different proposal is refused with 409 idempotency_key_reused. Keys are scoped to the authenticated actor and tree; failed requests record nothing. While moves are paused for the company the request returns 503 without reading or recording the key, so retry it later with the same key. A recorded outcome is kept for at least 24 hours and then removed by an hourly cleanup; until it is removed the same key still replays it, and only after removal is the key evaluated as a new request. Retry within 24 hours to be sure of a replay.
1 - 255^[!-~]+$Path Parameters
Body
An explicit unilevel move proposal. Actor and source are derived from authentication.
Response
Applied or authorized unchanged move.
curl -X POST 'https://api.fluid.app/api/member/v2026-10/team/01a08945-0cb7-7748-b66d-358cdca923b6/move' \
-H 'Authorization: Bearer <member-token>' \
-H 'Content-Type: application/json' \
--data \{\"move\":\{\"parent_node_id\":\"01a08945-0cbc-774c-a046-d7be609c4829\"\}\}import requests
url = "https://api.fluid.app/api/member/v2026-10/team/{id}/move"
payload = { "move": { "parent_node_id": "01a08945-0cbc-774c-a046-d7be609c4829" } }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({move: {parent_node_id: '01a08945-0cbc-774c-a046-d7be609c4829'}})
};
fetch('https://api.fluid.app/api/member/v2026-10/team/{id}/move', 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://api.fluid.app/api/member/v2026-10/team/{id}/move",
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([
'move' => [
'parent_node_id' => '01a08945-0cbc-774c-a046-d7be609c4829'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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://api.fluid.app/api/member/v2026-10/team/{id}/move"
payload := strings.NewReader("{\n \"move\": {\n \"parent_node_id\": \"01a08945-0cbc-774c-a046-d7be609c4829\"\n }\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(string(body))
}HttpResponse<String> response = Unirest.post("https://api.fluid.app/api/member/v2026-10/team/{id}/move")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"move\": {\n \"parent_node_id\": \"01a08945-0cbc-774c-a046-d7be609c4829\"\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/member/v2026-10/team/{id}/move")
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 \"move\": {\n \"parent_node_id\": \"01a08945-0cbc-774c-a046-d7be609c4829\"\n }\n}"
response = http.request(request)
puts response.read_body{
"changed": true,
"deferred": false,
"move_job": null,
"move_request": null,
"placement": {
"id": "01a08945-1a42-7048-a497-8bb5c88416ee",
"actor_id": "c0dd6812-0ba6-56d2-879c-a36112f813c2",
"actor_type": "Company::Member",
"effective_at": "2026-09-10T03:03:22.432397Z",
"ended_at": null,
"leg": null,
"member_id": "423f3c52-5440-5955-8e53-e2050d0b86b6",
"node_id": "01a08945-1a27-7dcf-9971-de363f3408ba",
"parent_node_id": "01a08945-1a2c-7fa7-9656-d36495b26b1c",
"reason": null,
"request_id": null,
"source": "rep",
"tree_id": "7096ad49-7117-53f6-8f7f-4805473d14c5"
},
"queued": false,
"status": 200,
"meta": {
"request_uuid": null,
"timestamp": "2026-09-10T03:03:22Z"
}
}{
"changed": false,
"deferred": true,
"move_job": {
"id": "01a08945-1911-7ca5-a402-e9558c7e5fcb",
"approval_request_id": null,
"attempts": 0,
"created_at": "2026-09-10T03:03:22.129487Z",
"failure_details": {},
"failure_type": null,
"finished_at": null,
"leg": null,
"node_id": "01a08945-0cb7-7748-b66d-358cdca923b6",
"parent_node_id": "01a08945-0cbc-774c-a046-d7be609c4829",
"placement_id": null,
"reason": null,
"requested_by_id": "c0dd6812-0ba6-56d2-879c-a36112f813c2",
"requested_by_type": "Company::Member",
"started_at": null,
"status": "pending",
"tree_id": "7096ad49-7117-53f6-8f7f-4805473d14c5"
},
"move_request": null,
"placement": null,
"queued": false,
"status": 202,
"meta": {
"request_uuid": null,
"timestamp": "2026-09-10T03:03:22Z"
}
}{
"message": "<string>",
"error": "<unknown>"
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}{
"error": "Rate limit exceeded",
"message": "Too many requests. Please wait before trying again.",
"retry_after": 30
}{
"status": 123,
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"request_uuid": "<string>",
"timestamp": "2023-11-07T05:31:56Z"
}
}