curl -X POST "https://api.phrase.com/v2/projects/:project_id/keys/:id/key_links" \
-u USERNAME_OR_ACCESS_TOKEN \
-H "Content-Type: application/json" \
-d '{"child_key_ids": ["ijkl9012mnop3456ijkl9012mnop3456", "abcd1234efgh5678abcd1234efgh5678"]}'import requests
url = "https://api.phrase.com/v2/projects/{project_id}/keys/{id}/key_links"
payload = { "child_key_ids": ["ijkl9012mnop3456ijkl9012mnop3456", "abcd1234efgh5678abcd1234efgh5678"] }
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({
child_key_ids: ['ijkl9012mnop3456ijkl9012mnop3456', 'abcd1234efgh5678abcd1234efgh5678']
})
};
fetch('https://api.phrase.com/v2/projects/{project_id}/keys/{id}/key_links', 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.phrase.com/v2/projects/{project_id}/keys/{id}/key_links",
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([
'child_key_ids' => [
'ijkl9012mnop3456ijkl9012mnop3456',
'abcd1234efgh5678abcd1234efgh5678'
]
]),
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://api.phrase.com/v2/projects/{project_id}/keys/{id}/key_links"
payload := strings.NewReader("{\n \"child_key_ids\": [\n \"ijkl9012mnop3456ijkl9012mnop3456\",\n \"abcd1234efgh5678abcd1234efgh5678\"\n ]\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://api.phrase.com/v2/projects/{project_id}/keys/{id}/key_links")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"child_key_ids\": [\n \"ijkl9012mnop3456ijkl9012mnop3456\",\n \"abcd1234efgh5678abcd1234efgh5678\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.phrase.com/v2/projects/{project_id}/keys/{id}/key_links")
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 \"child_key_ids\": [\n \"ijkl9012mnop3456ijkl9012mnop3456\",\n \"abcd1234efgh5678abcd1234efgh5678\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"created_at": "2024-03-15T10:22:00Z",
"updated_at": "2024-03-15T10:22:00Z",
"created_by": {
"id": "usr1a2b3c4d5e6f7a8b9c",
"username": "jane.doe",
"name": "Jane Doe",
"gravatar_uid": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"
},
"updated_by": {
"id": "usr1a2b3c4d5e6f7a8b9c",
"username": "jane.doe",
"name": "Jane Doe",
"gravatar_uid": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"
},
"account": {
"id": "acct9z8y7x6w5v4u3t2s",
"name": "Acme Translations",
"slug": "acme-translations",
"company": "Acme Corp",
"created_at": "2023-01-10T08:00:00Z",
"updated_at": "2023-06-01T12:00:00Z",
"company_logo_url": "https://example.com/logos/acme.png"
},
"parent": {
"id": "ijkl9012mnop3456ijkl9012",
"name": "home.hero.title",
"plural": false,
"use_ordinal_rules": false,
"data_type": "string",
"tags": [
"ui",
"homepage"
]
},
"children": [
{
"id": "ijkl9012mnop3456ijkl9012mnop3456",
"name": "home.hero.title_short",
"plural": false,
"use_ordinal_rules": false,
"data_type": "string",
"tags": [
"ui",
"homepage"
]
},
{
"id": "abcd1234efgh5678abcd1234efgh5678",
"name": "home.hero.title_long",
"plural": false,
"use_ordinal_rules": false,
"data_type": "string",
"tags": [
"ui",
"homepage"
]
}
]
}{
"message": "Validation Failed",
"errors": [
{
"resource": "Resource",
"field": "name",
"message": "can't be blank"
}
]
}Link child keys to a parent key
Designates a translation key as a parent and links one or more child keys to it. Once linked, child keys receive a special reference marker as their translation content, signalling that their translations are derived from the parent. Use this when you want to group related keys — for example, a short label and its long-form variant — so translators see them in context together.
Pass an empty child_key_ids array to mark the key as a parent without linking any children yet. Both the parent key and every child key must belong to the main project; branch keys cannot participate in key links. A child key can have at most one parent at a time; attempting to link a child that already has a parent returns a 422 error with code CHILD_IS_ALREADY_LINKED. Parent and child key plurality must match — linking a plural child to a non-plural parent (or vice versa) also returns a 422.
curl -X POST "https://api.phrase.com/v2/projects/:project_id/keys/:id/key_links" \
-u USERNAME_OR_ACCESS_TOKEN \
-H "Content-Type: application/json" \
-d '{"child_key_ids": ["ijkl9012mnop3456ijkl9012mnop3456", "abcd1234efgh5678abcd1234efgh5678"]}'import requests
url = "https://api.phrase.com/v2/projects/{project_id}/keys/{id}/key_links"
payload = { "child_key_ids": ["ijkl9012mnop3456ijkl9012mnop3456", "abcd1234efgh5678abcd1234efgh5678"] }
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({
child_key_ids: ['ijkl9012mnop3456ijkl9012mnop3456', 'abcd1234efgh5678abcd1234efgh5678']
})
};
fetch('https://api.phrase.com/v2/projects/{project_id}/keys/{id}/key_links', 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.phrase.com/v2/projects/{project_id}/keys/{id}/key_links",
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([
'child_key_ids' => [
'ijkl9012mnop3456ijkl9012mnop3456',
'abcd1234efgh5678abcd1234efgh5678'
]
]),
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://api.phrase.com/v2/projects/{project_id}/keys/{id}/key_links"
payload := strings.NewReader("{\n \"child_key_ids\": [\n \"ijkl9012mnop3456ijkl9012mnop3456\",\n \"abcd1234efgh5678abcd1234efgh5678\"\n ]\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://api.phrase.com/v2/projects/{project_id}/keys/{id}/key_links")
.header("Authorization", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"child_key_ids\": [\n \"ijkl9012mnop3456ijkl9012mnop3456\",\n \"abcd1234efgh5678abcd1234efgh5678\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.phrase.com/v2/projects/{project_id}/keys/{id}/key_links")
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 \"child_key_ids\": [\n \"ijkl9012mnop3456ijkl9012mnop3456\",\n \"abcd1234efgh5678abcd1234efgh5678\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"created_at": "2024-03-15T10:22:00Z",
"updated_at": "2024-03-15T10:22:00Z",
"created_by": {
"id": "usr1a2b3c4d5e6f7a8b9c",
"username": "jane.doe",
"name": "Jane Doe",
"gravatar_uid": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"
},
"updated_by": {
"id": "usr1a2b3c4d5e6f7a8b9c",
"username": "jane.doe",
"name": "Jane Doe",
"gravatar_uid": "a1b2c3d4e5f6a1b2c3d4e5f6a1b2c3d4"
},
"account": {
"id": "acct9z8y7x6w5v4u3t2s",
"name": "Acme Translations",
"slug": "acme-translations",
"company": "Acme Corp",
"created_at": "2023-01-10T08:00:00Z",
"updated_at": "2023-06-01T12:00:00Z",
"company_logo_url": "https://example.com/logos/acme.png"
},
"parent": {
"id": "ijkl9012mnop3456ijkl9012",
"name": "home.hero.title",
"plural": false,
"use_ordinal_rules": false,
"data_type": "string",
"tags": [
"ui",
"homepage"
]
},
"children": [
{
"id": "ijkl9012mnop3456ijkl9012mnop3456",
"name": "home.hero.title_short",
"plural": false,
"use_ordinal_rules": false,
"data_type": "string",
"tags": [
"ui",
"homepage"
]
},
{
"id": "abcd1234efgh5678abcd1234efgh5678",
"name": "home.hero.title_long",
"plural": false,
"use_ordinal_rules": false,
"data_type": "string",
"tags": [
"ui",
"homepage"
]
}
]
}{
"message": "Validation Failed",
"errors": [
{
"resource": "Resource",
"field": "name",
"message": "can't be blank"
}
]
}Authorizations
Enter your token in the format token TOKEN
Headers
Two-Factor-Authentication token (optional)
Body
Codes of the keys to link as children. Pass an empty array to mark the parent key without linking any children.
[
"ijkl9012mnop3456ijkl9012mnop3456",
"abcd1234efgh5678abcd1234efgh5678"
]
Response
Key link reference created.
The timestamp when the link was created.
The timestamp when the link was last updated.
The user who created the link.
Show child attributes
Show child attributes
{
"id": "abcd1234cdef1234abcd1234cdef1234",
"username": "johndoe",
"name": "John Doe",
"gravatar_uid": "205e460b479e2e5b48aec07710c08d50"
}
The user who last updated the link.
Show child attributes
Show child attributes
{
"id": "abcd1234cdef1234abcd1234cdef1234",
"username": "johndoe",
"name": "John Doe",
"gravatar_uid": "205e460b479e2e5b48aec07710c08d50"
}
The account associated with the link.
Show child attributes
Show child attributes
{
"id": "abcd1234",
"name": "Company Account",
"slug": "company_account",
"company": "My Awesome Company",
"created_at": "2015-01-28T09:52:53Z",
"updated_at": "2015-01-28T09:52:53Z",
"company_logo_url": "http://assets.example.com/company_logo.png"
}
The parent translation key in the link.
Show child attributes
Show child attributes
null
The child translation keys linked to the parent.
Show child attributes
Show child attributes
Was this page helpful?