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

# List Nodes

GET https://api.onepin.ai/api/v1/nodes

List all available node types with their input/output port schemas.

Returns the static structural definition for every node type registered in
the catalog — what ports each node exposes, their names, and expected data
shapes — without runtime-variable values such as available languages or the
TTS model catalog. This endpoint requires no `X-Workspace-Id` header and no
authentication, making it suitable for static documentation generation and
canvas layout tooling.

For the full runtime configuration options a user would pick when wiring up
a specific node (available target languages, provider/model options, voice
picker URL), use `GET /api/v2/nodes/{node_type}` instead.

Reference: https://onepin.ai/docs/reference/api-reference/nodes/list-nodes-api-v-1-nodes-get

## Servers

- `https://api.onepin.ai` (prod, default)
- `https://dev-api.onepin.ai` (dev)

## Response

### 200

Successful Response

- `data` (list of NodePortsOut, required)
- `meta` (Meta, required)
- `pagination` (PaginationMeta, required)

## Types

### NodePortsOut

- `node_type` (string, required)
- `display_name` (string, required)
- `description` (string, required)
- `version` (integer, required)
- `inputs` (list of PortOut, required)
- `outputs` (list of PortOut, required)
- `beta` (boolean, optional, default: false) — Whether this node carries a "beta" badge. Read from the live catalog per request, so staff can graduate a node without a release. Display only — it never affects availability. The static examples in this spec do not carry it and always show `false`; use the actual response.
- `input_schema` (map from string to any, optional)
- `config_schema` (map from string to any, optional)

### Meta

- `request_id` (string, required)
- `timestamp` (datetime, required)

### PaginationMeta

- `limit` (integer, required)
- `next` (string, optional, nullable)
- `prev` (string, optional, nullable)

### PortOut

- `name` (string, required)
- `fields` (list of string, optional)

## Examples

### source_script

**Response**

```json
{
  "data": [
    {
      "node_type": "source_script",
      "display_name": "Script Input",
      "description": "Upload or type your script",
      "version": 1,
      "inputs": [],
      "outputs": [
        {
          "name": "lines",
          "fields": [
            "locale_code",
            "script"
          ]
        }
      ],
      "beta": false,
      "input_schema": {
        "properties": {},
        "required": [],
        "type": "object"
      },
      "config_schema": {
        "csv_column": {
          "anyOf": [
            {
              "maxLength": 200,
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        },
        "csv_has_header": {
          "default": true,
          "type": "boolean"
        },
        "input_mode": {
          "default": "plain",
          "enum": [
            "plain",
            "markup"
          ],
          "type": "string"
        },
        "input_type": {
          "enum": [
            "text",
            "file",
            "media"
          ],
          "type": "string"
        },
        "source_language": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        },
        "text": {
          "default": "",
          "maxLength": 500000,
          "type": "string"
        },
        "upload_ids": {
          "items": {
            "format": "uuid",
            "type": "string"
          },
          "maxItems": 50,
          "type": "array"
        }
      }
    }
  ],
  "meta": {
    "request_id": "01ABC...",
    "timestamp": "2026-04-09T00:00:00Z"
  },
  "pagination": {
    "limit": 1
  }
}
```

**SDK Code**

```python source_script
import requests

url = "https://api.onepin.ai/api/v1/nodes"

response = requests.get(url)

print(response.json())
```

```javascript source_script
const url = 'https://api.onepin.ai/api/v1/nodes';
const options = {method: 'GET'};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go source_script
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.onepin.ai/api/v1/nodes"

	req, _ := http.NewRequest("GET", url, nil)

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby source_script
require 'uri'
require 'net/http'

url = URI("https://api.onepin.ai/api/v1/nodes")

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

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body
```

```java source_script
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.onepin.ai/api/v1/nodes")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.onepin.ai/api/v1/nodes');

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

```csharp source_script
using RestSharp;

var client = new RestClient("https://api.onepin.ai/api/v1/nodes");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
```

```swift source_script
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.onepin.ai/api/v1/nodes")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"

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()
```

### operator_translator

**Response**

```json
{
  "data": [
    {
      "node_type": "operator_translator",
      "display_name": "Translator",
      "description": "Translate into other languages",
      "version": 2,
      "inputs": [
        {
          "name": "lines",
          "fields": [
            "locale_code",
            "script"
          ]
        }
      ],
      "outputs": [
        {
          "name": "lines",
          "fields": [
            "locale_code",
            "script"
          ]
        }
      ],
      "beta": false,
      "input_schema": {
        "properties": {
          "lines": {
            "items": {
              "properties": {
                "locale_code": {
                  "default": [
                    "en-US"
                  ],
                  "description": "Locale code for the line.",
                  "items": {
                    "type": "string"
                  },
                  "maxItems": 1,
                  "title": "Locale code",
                  "type": "array",
                  "x-donut-ui": "locale-code"
                },
                "script": {
                  "default": "",
                  "description": "Line script or reference text.",
                  "title": "Script",
                  "type": "string",
                  "x-donut-ui": "textarea"
                }
              },
              "required": [
                "locale_code",
                "script"
              ],
              "type": "object"
            },
            "minItems": 1,
            "title": "Lines",
            "type": "array"
          }
        },
        "required": [
          "lines"
        ],
        "type": "object"
      },
      "config_schema": {
        "target_languages": {
          "items": {
            "type": "string"
          },
          "maxItems": 30,
          "minItems": 1,
          "type": "array"
        }
      }
    }
  ],
  "meta": {
    "request_id": "01ABC...",
    "timestamp": "2026-04-09T00:00:00Z"
  },
  "pagination": {
    "limit": 1
  }
}
```

**SDK Code**

```python operator_translator
import requests

url = "https://api.onepin.ai/api/v1/nodes"

response = requests.get(url)

print(response.json())
```

```javascript operator_translator
const url = 'https://api.onepin.ai/api/v1/nodes';
const options = {method: 'GET'};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go operator_translator
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.onepin.ai/api/v1/nodes"

	req, _ := http.NewRequest("GET", url, nil)

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby operator_translator
require 'uri'
require 'net/http'

url = URI("https://api.onepin.ai/api/v1/nodes")

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

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body
```

```java operator_translator
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.onepin.ai/api/v1/nodes")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.onepin.ai/api/v1/nodes');

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

```csharp operator_translator
using RestSharp;

var client = new RestClient("https://api.onepin.ai/api/v1/nodes");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
```

```swift operator_translator
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.onepin.ai/api/v1/nodes")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"

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()
```

### operator_normalizer

**Response**

```json
{
  "data": [
    {
      "node_type": "operator_normalizer",
      "display_name": "Normalizer",
      "description": "Normalization",
      "version": 1,
      "inputs": [
        {
          "name": "lines",
          "fields": [
            "locale_code",
            "script"
          ]
        }
      ],
      "outputs": [
        {
          "name": "lines",
          "fields": [
            "script"
          ]
        }
      ],
      "beta": false,
      "input_schema": {
        "properties": {
          "lines": {
            "items": {
              "properties": {
                "locale_code": {
                  "default": [
                    "en-US"
                  ],
                  "description": "Locale code for the line.",
                  "items": {
                    "type": "string"
                  },
                  "maxItems": 1,
                  "title": "Locale code",
                  "type": "array",
                  "x-donut-ui": "locale-code"
                },
                "script": {
                  "default": "",
                  "description": "Line script or reference text.",
                  "title": "Script",
                  "type": "string",
                  "x-donut-ui": "textarea"
                }
              },
              "required": [
                "locale_code",
                "script"
              ],
              "type": "object"
            },
            "minItems": 1,
            "title": "Lines",
            "type": "array"
          }
        },
        "required": [
          "lines"
        ],
        "type": "object"
      },
      "config_schema": {
        "engine": {
          "const": "llm",
          "default": "llm",
          "type": "string"
        },
        "target_locale": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ]
        }
      }
    }
  ],
  "meta": {
    "request_id": "01ABC...",
    "timestamp": "2026-04-09T00:00:00Z"
  },
  "pagination": {
    "limit": 1
  }
}
```

**SDK Code**

```python operator_normalizer
import requests

url = "https://api.onepin.ai/api/v1/nodes"

response = requests.get(url)

print(response.json())
```

```javascript operator_normalizer
const url = 'https://api.onepin.ai/api/v1/nodes';
const options = {method: 'GET'};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go operator_normalizer
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.onepin.ai/api/v1/nodes"

	req, _ := http.NewRequest("GET", url, nil)

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby operator_normalizer
require 'uri'
require 'net/http'

url = URI("https://api.onepin.ai/api/v1/nodes")

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

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body
```

```java operator_normalizer
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.onepin.ai/api/v1/nodes")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.onepin.ai/api/v1/nodes');

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

```csharp operator_normalizer
using RestSharp;

var client = new RestClient("https://api.onepin.ai/api/v1/nodes");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
```

```swift operator_normalizer
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.onepin.ai/api/v1/nodes")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"

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()
```

### operator_generator

**Response**

```json
{
  "data": [
    {
      "node_type": "operator_generator",
      "display_name": "Voice Generator",
      "description": "TTS engine - voice generation",
      "version": 3,
      "inputs": [
        {
          "name": "lines",
          "fields": [
            "locale_code",
            "script"
          ]
        }
      ],
      "outputs": [
        {
          "name": "lines",
          "fields": [
            "audio_files"
          ]
        }
      ],
      "beta": false,
      "input_schema": {
        "properties": {
          "lines": {
            "items": {
              "properties": {
                "locale_code": {
                  "default": [
                    "en-US"
                  ],
                  "description": "Locale code for the line.",
                  "items": {
                    "type": "string"
                  },
                  "maxItems": 1,
                  "title": "Locale code",
                  "type": "array",
                  "x-donut-ui": "locale-code"
                },
                "script": {
                  "default": "",
                  "description": "Line script or reference text.",
                  "title": "Script",
                  "type": "string",
                  "x-donut-ui": "textarea"
                }
              },
              "required": [
                "locale_code",
                "script"
              ],
              "type": "object"
            },
            "minItems": 1,
            "title": "Lines",
            "type": "array"
          }
        },
        "required": [
          "lines"
        ],
        "type": "object"
      },
      "config_schema": {
        "target_locale": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Target Locale"
        },
        "voice_map": {
          "additionalProperties": {
            "items": {
              "description": "Per-language voice assignment for operator generation.",
              "properties": {
                "canonical_controls": {
                  "anyOf": [
                    {
                      "additionalProperties": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "integer"
                          },
                          {
                            "type": "number"
                          }
                        ]
                      },
                      "type": "object"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "title": "Canonical Controls"
                },
                "catalog_voice_id": {
                  "anyOf": [
                    {
                      "format": "uuid",
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "title": "Catalog Voice Id"
                },
                "model": {
                  "maxLength": 200,
                  "minLength": 1,
                  "title": "Model",
                  "type": "string"
                },
                "provider": {
                  "maxLength": 100,
                  "minLength": 1,
                  "title": "Provider",
                  "type": "string"
                },
                "provider_config": {
                  "anyOf": [
                    {
                      "additionalProperties": {
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "integer"
                          },
                          {
                            "type": "number"
                          },
                          {
                            "type": "boolean"
                          }
                        ]
                      },
                      "type": "object"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "title": "Provider Config"
                },
                "voice_id": {
                  "maxLength": 255,
                  "minLength": 1,
                  "title": "Voice Id",
                  "type": "string"
                },
                "voice_name": {
                  "anyOf": [
                    {
                      "maxLength": 255,
                      "type": "string"
                    },
                    {
                      "type": "null"
                    }
                  ],
                  "title": "Voice Name"
                }
              },
              "required": [
                "voice_id",
                "provider",
                "model"
              ],
              "title": "VoiceAssignment",
              "type": "object"
            },
            "type": "array"
          },
          "title": "Voice Map",
          "type": "object"
        }
      }
    }
  ],
  "meta": {
    "request_id": "01ABC...",
    "timestamp": "2026-04-09T00:00:00Z"
  },
  "pagination": {
    "limit": 1
  }
}
```

**SDK Code**

```python operator_generator
import requests

url = "https://api.onepin.ai/api/v1/nodes"

response = requests.get(url)

print(response.json())
```

```javascript operator_generator
const url = 'https://api.onepin.ai/api/v1/nodes';
const options = {method: 'GET'};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go operator_generator
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.onepin.ai/api/v1/nodes"

	req, _ := http.NewRequest("GET", url, nil)

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby operator_generator
require 'uri'
require 'net/http'

url = URI("https://api.onepin.ai/api/v1/nodes")

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

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body
```

```java operator_generator
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.onepin.ai/api/v1/nodes")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.onepin.ai/api/v1/nodes');

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

```csharp operator_generator
using RestSharp;

var client = new RestClient("https://api.onepin.ai/api/v1/nodes");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
```

```swift operator_generator
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.onepin.ai/api/v1/nodes")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"

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()
```

### operator_phoneme_injector

**Response**

```json
{
  "data": [
    {
      "node_type": "operator_phoneme_injector",
      "display_name": "Phoneme Injector",
      "description": "Work out how each word should be pronounced in context, so the Pronunciation Check knows what's correct",
      "version": 1,
      "inputs": [
        {
          "name": "lines",
          "fields": [
            "audio_files",
            "locale_code",
            "script"
          ]
        }
      ],
      "outputs": [
        {
          "name": "lines",
          "fields": [
            "phoneme_map"
          ]
        }
      ],
      "beta": false,
      "input_schema": {
        "properties": {
          "lines": {
            "items": {
              "properties": {
                "locale_code": {
                  "default": [
                    "en-US"
                  ],
                  "description": "Locale code for the line.",
                  "items": {
                    "type": "string"
                  },
                  "maxItems": 1,
                  "title": "Locale code",
                  "type": "array",
                  "x-donut-ui": "locale-code"
                },
                "script": {
                  "default": "",
                  "description": "Line script or reference text.",
                  "title": "Script",
                  "type": "string",
                  "x-donut-ui": "textarea"
                }
              },
              "required": [
                "locale_code",
                "script"
              ],
              "type": "object"
            },
            "minItems": 1,
            "title": "Lines",
            "type": "array"
          }
        },
        "required": [
          "lines"
        ],
        "type": "object"
      },
      "config_schema": {
        "exclude_address_rows": {
          "default": true,
          "type": "boolean"
        },
        "llm_candidate_filter": {
          "default": true,
          "type": "boolean"
        },
        "max_ngram": {
          "default": 1,
          "maximum": 5,
          "minimum": 1,
          "type": "integer"
        },
        "use_derived_word_parts": {
          "default": true,
          "type": "boolean"
        }
      }
    }
  ],
  "meta": {
    "request_id": "01ABC...",
    "timestamp": "2026-04-09T00:00:00Z"
  },
  "pagination": {
    "limit": 1
  }
}
```

**SDK Code**

```python operator_phoneme_injector
import requests

url = "https://api.onepin.ai/api/v1/nodes"

response = requests.get(url)

print(response.json())
```

```javascript operator_phoneme_injector
const url = 'https://api.onepin.ai/api/v1/nodes';
const options = {method: 'GET'};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go operator_phoneme_injector
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.onepin.ai/api/v1/nodes"

	req, _ := http.NewRequest("GET", url, nil)

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby operator_phoneme_injector
require 'uri'
require 'net/http'

url = URI("https://api.onepin.ai/api/v1/nodes")

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

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body
```

```java operator_phoneme_injector
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.onepin.ai/api/v1/nodes")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.onepin.ai/api/v1/nodes');

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

```csharp operator_phoneme_injector
using RestSharp;

var client = new RestClient("https://api.onepin.ai/api/v1/nodes");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
```

```swift operator_phoneme_injector
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.onepin.ai/api/v1/nodes")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"

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()
```

### operator_pronunciation_corrector

**Response**

```json
{
  "data": [
    {
      "node_type": "operator_pronunciation_corrector",
      "display_name": "Pronunciation Corrector",
      "description": "Automatically fix mispronounced words, keeping the same voice",
      "version": 1,
      "inputs": [
        {
          "name": "lines",
          "fields": [
            "audio_files",
            "locale_code",
            "script"
          ]
        }
      ],
      "outputs": [
        {
          "name": "lines",
          "fields": [
            "audio_files"
          ]
        }
      ],
      "beta": false,
      "input_schema": {
        "properties": {
          "lines": {
            "items": {
              "properties": {
                "audio_upload_id": {
                  "description": "Confirmed playground audio upload to hydrate into audio_files.",
                  "format": "uuid",
                  "title": "Audio file",
                  "type": "string",
                  "x-donut-hydrates": "audio_files",
                  "x-donut-ui": "audio-upload",
                  "x-donut-upload-category": "dictionary"
                },
                "locale_code": {
                  "default": [
                    "en-US"
                  ],
                  "description": "Locale code for the line.",
                  "items": {
                    "type": "string"
                  },
                  "maxItems": 1,
                  "title": "Locale code",
                  "type": "array",
                  "x-donut-ui": "locale-code"
                },
                "mispronounced": {
                  "description": "Optional (standalone only): the words the corrector should re-splice and their target IPA. `index` is the 0-based position of the word in `script` split on whitespace. The execute endpoint wraps these into a PED verdict on the take hydrated from audio_upload_id, so you supply only these entries — not the validator_kind/has_error wrapper.",
                  "items": {
                    "properties": {
                      "index": {
                        "title": "Token index",
                        "type": "integer"
                      },
                      "ipa_intended": {
                        "title": "Intended IPA",
                        "type": "string"
                      },
                      "word": {
                        "title": "Word",
                        "type": "string"
                      }
                    },
                    "required": [
                      "word",
                      "index",
                      "ipa_intended"
                    ],
                    "type": "object"
                  },
                  "title": "Mispronounced words",
                  "type": "array",
                  "x-donut-ui": "json"
                },
                "phoneme_map": {
                  "additionalProperties": {
                    "type": "string"
                  },
                  "description": "Optional per-word IPA pronunciation overrides as a {word: IPA} object, e.g. {\"tomato\": \"təˈmɑːtoʊ\"}. This is the SOURCE of the corrected pronunciation: a flagged word present here is respliced with this IPA, and a flagged word absent from it is skipped rather than corrected against the detector's guess. In a workflow the phoneme injector attaches it; supply it directly to test standalone. OMIT the field entirely to fall back to the detector's ipa_intended — an EMPTY object means the dictionary was consulted and had nothing, so every flagged word is skipped as no_dictionary_entry.",
                  "title": "Phoneme map",
                  "type": "object",
                  "x-donut-ui": "json"
                },
                "script": {
                  "default": "",
                  "description": "Line script or reference text.",
                  "title": "Script",
                  "type": "string",
                  "x-donut-ui": "textarea"
                }
              },
              "required": [
                "audio_upload_id",
                "locale_code",
                "script"
              ],
              "type": "object"
            },
            "minItems": 1,
            "title": "Lines",
            "type": "array"
          }
        },
        "required": [
          "lines"
        ],
        "type": "object"
      },
      "config_schema": {
        "fallback_to_detector_ipa": {
          "default": true,
          "type": "boolean"
        },
        "n_candidates": {
          "default": 2,
          "maximum": 8,
          "minimum": 1,
          "type": "integer"
        },
        "seed": {
          "anyOf": [
            {
              "maximum": 2147483647,
              "minimum": 0,
              "type": "integer"
            },
            {
              "type": "null"
            }
          ]
        },
        "target_ipa_source": {
          "default": "dictionary",
          "description": "Which IPA the correction targets: \"dictionary\" reads the built-in pronunciation reference; \"ped\" trusts the pronunciation check's own transcription.",
          "enum": [
            "dictionary",
            "ped"
          ],
          "type": "string"
        }
      }
    }
  ],
  "meta": {
    "request_id": "01ABC...",
    "timestamp": "2026-04-09T00:00:00Z"
  },
  "pagination": {
    "limit": 1
  }
}
```

**SDK Code**

```python operator_pronunciation_corrector
import requests

url = "https://api.onepin.ai/api/v1/nodes"

response = requests.get(url)

print(response.json())
```

```javascript operator_pronunciation_corrector
const url = 'https://api.onepin.ai/api/v1/nodes';
const options = {method: 'GET'};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go operator_pronunciation_corrector
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.onepin.ai/api/v1/nodes"

	req, _ := http.NewRequest("GET", url, nil)

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby operator_pronunciation_corrector
require 'uri'
require 'net/http'

url = URI("https://api.onepin.ai/api/v1/nodes")

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

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body
```

```java operator_pronunciation_corrector
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.onepin.ai/api/v1/nodes")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.onepin.ai/api/v1/nodes');

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

```csharp operator_pronunciation_corrector
using RestSharp;

var client = new RestClient("https://api.onepin.ai/api/v1/nodes");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
```

```swift operator_pronunciation_corrector
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.onepin.ai/api/v1/nodes")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"

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()
```

### sink_preview

**Response**

```json
{
  "data": [
    {
      "node_type": "sink_preview",
      "display_name": "Export",
      "description": "Export final audio",
      "version": 1,
      "inputs": [
        {
          "name": "lines",
          "fields": [
            "audio_files"
          ]
        }
      ],
      "outputs": [],
      "beta": false,
      "input_schema": {
        "properties": {
          "lines": {
            "items": {
              "properties": {
                "audio_upload_id": {
                  "description": "Confirmed playground audio upload to hydrate into audio_files.",
                  "format": "uuid",
                  "title": "Audio file",
                  "type": "string",
                  "x-donut-hydrates": "audio_files",
                  "x-donut-ui": "audio-upload",
                  "x-donut-upload-category": "dictionary"
                }
              },
              "required": [
                "audio_upload_id"
              ],
              "type": "object"
            },
            "minItems": 1,
            "title": "Lines",
            "type": "array"
          }
        },
        "required": [
          "lines"
        ],
        "type": "object"
      },
      "config_schema": {
        "format": {
          "default": "wav",
          "enum": [
            "wav",
            "mp3"
          ],
          "type": "string"
        }
      }
    }
  ],
  "meta": {
    "request_id": "01ABC...",
    "timestamp": "2026-04-09T00:00:00Z"
  },
  "pagination": {
    "limit": 1
  }
}
```

**SDK Code**

```python sink_preview
import requests

url = "https://api.onepin.ai/api/v1/nodes"

response = requests.get(url)

print(response.json())
```

```javascript sink_preview
const url = 'https://api.onepin.ai/api/v1/nodes';
const options = {method: 'GET'};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go sink_preview
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.onepin.ai/api/v1/nodes"

	req, _ := http.NewRequest("GET", url, nil)

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby sink_preview
require 'uri'
require 'net/http'

url = URI("https://api.onepin.ai/api/v1/nodes")

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

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body
```

```java sink_preview
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.onepin.ai/api/v1/nodes")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.onepin.ai/api/v1/nodes');

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

```csharp sink_preview
using RestSharp;

var client = new RestClient("https://api.onepin.ai/api/v1/nodes");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
```

```swift sink_preview
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.onepin.ai/api/v1/nodes")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"

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()
```

### validator_error_rate

**Response**

```json
{
  "data": [
    {
      "node_type": "validator_error_rate",
      "display_name": "Word Accuracy",
      "description": "Target word accuracy check",
      "version": 1,
      "inputs": [
        {
          "name": "lines",
          "fields": [
            "audio_files",
            "locale_code",
            "script"
          ]
        }
      ],
      "outputs": [
        {
          "name": "pass",
          "fields": [
            "validation"
          ]
        },
        {
          "name": "fail",
          "fields": [
            "retry_counts",
            "validation"
          ]
        }
      ],
      "beta": false,
      "input_schema": {
        "properties": {
          "lines": {
            "items": {
              "properties": {
                "audio_upload_id": {
                  "description": "Confirmed playground audio upload to hydrate into audio_files.",
                  "format": "uuid",
                  "title": "Audio file",
                  "type": "string",
                  "x-donut-hydrates": "audio_files",
                  "x-donut-ui": "audio-upload",
                  "x-donut-upload-category": "dictionary"
                },
                "locale_code": {
                  "default": [
                    "en-US"
                  ],
                  "description": "Locale code for the line.",
                  "items": {
                    "type": "string"
                  },
                  "maxItems": 1,
                  "title": "Locale code",
                  "type": "array",
                  "x-donut-ui": "locale-code"
                },
                "script": {
                  "default": "",
                  "description": "Line script or reference text.",
                  "title": "Script",
                  "type": "string",
                  "x-donut-ui": "textarea"
                }
              },
              "required": [
                "audio_upload_id",
                "locale_code",
                "script"
              ],
              "type": "object"
            },
            "minItems": 1,
            "title": "Lines",
            "type": "array"
          }
        },
        "required": [
          "lines"
        ],
        "type": "object"
      },
      "config_schema": {
        "max_retries": {
          "default": 3,
          "maximum": 50,
          "minimum": 1,
          "type": "integer"
        },
        "threshold": {
          "default": 93,
          "maximum": 99,
          "minimum": 70,
          "type": "number"
        }
      }
    }
  ],
  "meta": {
    "request_id": "01ABC...",
    "timestamp": "2026-04-09T00:00:00Z"
  },
  "pagination": {
    "limit": 1
  }
}
```

**SDK Code**

```python validator_error_rate
import requests

url = "https://api.onepin.ai/api/v1/nodes"

response = requests.get(url)

print(response.json())
```

```javascript validator_error_rate
const url = 'https://api.onepin.ai/api/v1/nodes';
const options = {method: 'GET'};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go validator_error_rate
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.onepin.ai/api/v1/nodes"

	req, _ := http.NewRequest("GET", url, nil)

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby validator_error_rate
require 'uri'
require 'net/http'

url = URI("https://api.onepin.ai/api/v1/nodes")

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

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body
```

```java validator_error_rate
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.onepin.ai/api/v1/nodes")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.onepin.ai/api/v1/nodes');

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

```csharp validator_error_rate
using RestSharp;

var client = new RestClient("https://api.onepin.ai/api/v1/nodes");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
```

```swift validator_error_rate
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.onepin.ai/api/v1/nodes")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"

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()
```

### validator_naturalness

**Response**

```json
{
  "data": [
    {
      "node_type": "validator_naturalness",
      "display_name": "Naturalness",
      "description": "Score naturalness of generated speech",
      "version": 1,
      "inputs": [
        {
          "name": "lines",
          "fields": [
            "audio_files",
            "locale_code",
            "script"
          ]
        }
      ],
      "outputs": [
        {
          "name": "pass",
          "fields": [
            "validation"
          ]
        },
        {
          "name": "fail",
          "fields": [
            "retry_counts",
            "validation"
          ]
        }
      ],
      "beta": false,
      "input_schema": {
        "properties": {
          "lines": {
            "items": {
              "properties": {
                "audio_upload_id": {
                  "description": "Confirmed playground audio upload to hydrate into audio_files.",
                  "format": "uuid",
                  "title": "Audio file",
                  "type": "string",
                  "x-donut-hydrates": "audio_files",
                  "x-donut-ui": "audio-upload",
                  "x-donut-upload-category": "dictionary"
                },
                "locale_code": {
                  "default": [
                    "en-US"
                  ],
                  "description": "Locale code for the line.",
                  "items": {
                    "type": "string"
                  },
                  "maxItems": 1,
                  "title": "Locale code",
                  "type": "array",
                  "x-donut-ui": "locale-code"
                },
                "script": {
                  "default": "",
                  "description": "Line script or reference text.",
                  "title": "Script",
                  "type": "string",
                  "x-donut-ui": "textarea"
                }
              },
              "required": [
                "audio_upload_id",
                "locale_code",
                "script"
              ],
              "type": "object"
            },
            "minItems": 1,
            "title": "Lines",
            "type": "array"
          }
        },
        "required": [
          "lines"
        ],
        "type": "object"
      },
      "config_schema": {
        "max_retries": {
          "default": 3,
          "maximum": 50,
          "minimum": 1,
          "type": "integer"
        },
        "threshold": {
          "default": 70,
          "maximum": 100,
          "minimum": 0,
          "type": "number"
        }
      }
    }
  ],
  "meta": {
    "request_id": "01ABC...",
    "timestamp": "2026-04-09T00:00:00Z"
  },
  "pagination": {
    "limit": 1
  }
}
```

**SDK Code**

```python validator_naturalness
import requests

url = "https://api.onepin.ai/api/v1/nodes"

response = requests.get(url)

print(response.json())
```

```javascript validator_naturalness
const url = 'https://api.onepin.ai/api/v1/nodes';
const options = {method: 'GET'};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go validator_naturalness
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.onepin.ai/api/v1/nodes"

	req, _ := http.NewRequest("GET", url, nil)

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby validator_naturalness
require 'uri'
require 'net/http'

url = URI("https://api.onepin.ai/api/v1/nodes")

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

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body
```

```java validator_naturalness
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.onepin.ai/api/v1/nodes")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.onepin.ai/api/v1/nodes');

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

```csharp validator_naturalness
using RestSharp;

var client = new RestClient("https://api.onepin.ai/api/v1/nodes");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
```

```swift validator_naturalness
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.onepin.ai/api/v1/nodes")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"

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()
```

### validator_noise

**Response**

```json
{
  "data": [
    {
      "node_type": "validator_noise",
      "display_name": "Clarity",
      "description": "Check the clarity of generated audio (flags background noise / artifacts)",
      "version": 1,
      "inputs": [
        {
          "name": "lines",
          "fields": [
            "audio_files",
            "locale_code",
            "script"
          ]
        }
      ],
      "outputs": [
        {
          "name": "pass",
          "fields": [
            "validation"
          ]
        },
        {
          "name": "fail",
          "fields": [
            "retry_counts",
            "validation"
          ]
        }
      ],
      "beta": false,
      "input_schema": {
        "properties": {
          "lines": {
            "items": {
              "properties": {
                "audio_upload_id": {
                  "description": "Confirmed playground audio upload to hydrate into audio_files.",
                  "format": "uuid",
                  "title": "Audio file",
                  "type": "string",
                  "x-donut-hydrates": "audio_files",
                  "x-donut-ui": "audio-upload",
                  "x-donut-upload-category": "dictionary"
                },
                "locale_code": {
                  "default": [
                    "en-US"
                  ],
                  "description": "Locale code for the line.",
                  "items": {
                    "type": "string"
                  },
                  "maxItems": 1,
                  "title": "Locale code",
                  "type": "array",
                  "x-donut-ui": "locale-code"
                },
                "script": {
                  "default": "",
                  "description": "Line script or reference text.",
                  "title": "Script",
                  "type": "string",
                  "x-donut-ui": "textarea"
                }
              },
              "required": [
                "audio_upload_id",
                "locale_code",
                "script"
              ],
              "type": "object"
            },
            "minItems": 1,
            "title": "Lines",
            "type": "array"
          }
        },
        "required": [
          "lines"
        ],
        "type": "object"
      },
      "config_schema": {
        "max_retries": {
          "default": 3,
          "maximum": 50,
          "minimum": 1,
          "type": "integer"
        },
        "threshold": {
          "default": 70,
          "maximum": 100,
          "minimum": 0,
          "type": "number"
        }
      }
    }
  ],
  "meta": {
    "request_id": "01ABC...",
    "timestamp": "2026-04-09T00:00:00Z"
  },
  "pagination": {
    "limit": 1
  }
}
```

**SDK Code**

```python validator_noise
import requests

url = "https://api.onepin.ai/api/v1/nodes"

response = requests.get(url)

print(response.json())
```

```javascript validator_noise
const url = 'https://api.onepin.ai/api/v1/nodes';
const options = {method: 'GET'};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go validator_noise
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.onepin.ai/api/v1/nodes"

	req, _ := http.NewRequest("GET", url, nil)

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby validator_noise
require 'uri'
require 'net/http'

url = URI("https://api.onepin.ai/api/v1/nodes")

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

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body
```

```java validator_noise
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.onepin.ai/api/v1/nodes")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.onepin.ai/api/v1/nodes');

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

```csharp validator_noise
using RestSharp;

var client = new RestClient("https://api.onepin.ai/api/v1/nodes");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
```

```swift validator_noise
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.onepin.ai/api/v1/nodes")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"

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()
```

### validator_pronunciation

**Response**

```json
{
  "data": [
    {
      "node_type": "validator_pronunciation",
      "display_name": "Pronunciation",
      "description": "Check each word is pronounced correctly, sound by sound",
      "version": 1,
      "inputs": [
        {
          "name": "lines",
          "fields": [
            "audio_files",
            "locale_code",
            "script"
          ]
        }
      ],
      "outputs": [
        {
          "name": "pass",
          "fields": [
            "validation"
          ]
        },
        {
          "name": "fail",
          "fields": [
            "retry_counts",
            "validation"
          ]
        }
      ],
      "beta": false,
      "input_schema": {
        "properties": {
          "lines": {
            "items": {
              "properties": {
                "audio_upload_id": {
                  "description": "Confirmed playground audio upload to hydrate into audio_files.",
                  "format": "uuid",
                  "title": "Audio file",
                  "type": "string",
                  "x-donut-hydrates": "audio_files",
                  "x-donut-ui": "audio-upload",
                  "x-donut-upload-category": "dictionary"
                },
                "locale_code": {
                  "default": [
                    "en-US"
                  ],
                  "description": "Locale code for the line.",
                  "items": {
                    "type": "string"
                  },
                  "maxItems": 1,
                  "title": "Locale code",
                  "type": "array",
                  "x-donut-ui": "locale-code"
                },
                "phoneme_map": {
                  "additionalProperties": {
                    "type": "string"
                  },
                  "description": "Optional per-word IPA pronunciation overrides as a {word: IPA} object, e.g. {\"tomato\": \"təˈmɑːtoʊ\"}. In a workflow the phoneme injector attaches this on a validator's fail path; supply it directly to test this node standalone. Words absent from the map are graded by spelling.",
                  "title": "Phoneme map",
                  "type": "object",
                  "x-donut-ui": "json"
                },
                "script": {
                  "default": "",
                  "description": "Line script or reference text.",
                  "title": "Script",
                  "type": "string",
                  "x-donut-ui": "textarea"
                }
              },
              "required": [
                "audio_upload_id",
                "locale_code",
                "script"
              ],
              "type": "object"
            },
            "minItems": 1,
            "title": "Lines",
            "type": "array"
          }
        },
        "required": [
          "lines"
        ],
        "type": "object"
      },
      "config_schema": {
        "k": {
          "default": 1,
          "exclusiveMinimum": 0,
          "maximum": 10,
          "type": "number"
        },
        "max_retries": {
          "default": 3,
          "maximum": 50,
          "minimum": 1,
          "type": "integer"
        },
        "threshold": {
          "default": 99,
          "maximum": 100,
          "minimum": 0,
          "type": "number"
        }
      }
    }
  ],
  "meta": {
    "request_id": "01ABC...",
    "timestamp": "2026-04-09T00:00:00Z"
  },
  "pagination": {
    "limit": 1
  }
}
```

**SDK Code**

```python validator_pronunciation
import requests

url = "https://api.onepin.ai/api/v1/nodes"

response = requests.get(url)

print(response.json())
```

```javascript validator_pronunciation
const url = 'https://api.onepin.ai/api/v1/nodes';
const options = {method: 'GET'};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go validator_pronunciation
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.onepin.ai/api/v1/nodes"

	req, _ := http.NewRequest("GET", url, nil)

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby validator_pronunciation
require 'uri'
require 'net/http'

url = URI("https://api.onepin.ai/api/v1/nodes")

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

request = Net::HTTP::Get.new(url)

response = http.request(request)
puts response.read_body
```

```java validator_pronunciation
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.get("https://api.onepin.ai/api/v1/nodes")
  .asString();
```

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

$client = new \GuzzleHttp\Client();

$response = $client->request('GET', 'https://api.onepin.ai/api/v1/nodes');

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

```csharp validator_pronunciation
using RestSharp;

var client = new RestClient("https://api.onepin.ai/api/v1/nodes");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
```

```swift validator_pronunciation
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.onepin.ai/api/v1/nodes")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "GET"

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()
```