> For the complete documentation index, see [llms.txt](https://docs.tonic.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.tonic.ai/app/api/api-examples.md).

# Example script: Starting a data generation job

Kicking off a data generation using Python. Note the version that this script was tested against.

{% tabs %}
{% tab title="Python" %}
{% code title="tonic\_generation.py" overflow="wrap" %}

```python
# Note that our API does not guarantee backward compatibility.
# For the endpoints and parameters for your exact version, view the 
# Swagger API documentation that comes with your instance.
# If you use Structural Cloud, the API documentation is at:
# https://app.tonic.ai/apidocs/index.html

# Tested 2026.07.08 with Tonic API v2024.01.0

import json
import requests

TONIC_API_KEY = "<<STRUCTURAL API TOKEN>>"
TONIC_URL = "https://<<STRUCTURAL HOSTNAME>>"
WORKSPACE_NAME = "<<STRUCTURAL WORKSPACE>>"


class TonicSession:
    def __init__(self, base_url, api_key):
        self._base_url = base_url
        self._session = requests.Session()
        self._session.headers.update({"Authorization": "Apikey {}".format(api_key)})

    def _get_url(self, api_snippet):
        return "{}{}".format(self._base_url, api_snippet)

    def generate_data(self, workspace_id):
        generate_data_url = self._get_url("/api/generateData/start")
        params = {"workspaceId": workspace_id}
        r = self._session.post(generate_data_url, params=params)
        if r.ok:
            print("Data generation started")
            print(json.dumps(r.json(), indent=2))
        else:
            r.raise_for_status()

    def generate_data_status(self, workspace_id):
        generate_data_status_url = self._get_url("/api/generateData")
        params = {"workspaceId": workspace_id}
        r = self._session.get(generate_data_status_url, params=params)
        if r.ok:
            print(json.dumps(r.json(), indent=2))
        else:
            r.raise_for_status()

    def find_workspace_by_name(self, workspace_name):
        search_url = self._get_url("/api/Workspace/search")
        params = {"filters[name]": workspace_name}
        r = self._session.get(search_url, params=params)
        if r.ok:
            records = r.json().get("records", [])
            matches = [w for w in records if w["workspaceName"] == workspace_name]
            if len(matches) == 1:
                return matches[0]["id"]
            elif len(matches) == 0:
                raise RuntimeError("No workspace found with name: {}".format(workspace_name))
            else:
                raise RuntimeError("Multiple workspaces found with name: {}".format(workspace_name))
        else:
            r.raise_for_status()


def main():
    session = TonicSession(TONIC_URL, TONIC_API_KEY)

    print("=== GET /api/Workspace/search ===")
    workspace_id = session.find_workspace_by_name(WORKSPACE_NAME)
    print("Found workspace: {} ({})".format(WORKSPACE_NAME, workspace_id))

    print("\n=== GET /api/generateData (status) ===")
    session.generate_data_status(workspace_id)

    print("\n=== POST /api/generateData/start ===")
    session.generate_data(workspace_id)


if __name__ == "__main__":
    main()
```

{% endcode %}
{% endtab %}

{% tab title="Node" %}
{% code title="tonic\_generation.js" overflow="wrap" %}

```javascript
// Note that our API does not guarantee backward compatibility.
// For the endpoints and parameters for your exact version, view the 
// Swagger API documentation that comes with your instance.
// If you use Structural Cloud, the API documentation is at:
// https://app.tonic.ai/apidocs/index.html

// Tested 2026.07.08 with Tonic API v2024.01.0

// Install node-fetch with npm install node-fetch
const fetch = require('node-fetch');

const apiKey = "<<STRUCTURAL API TOKEN>>";
const workspaceName = "<<STRUCTURAL WORKSPACE>>";
const tonicUrl = "https://<<STRUCTURAL HOSTNAME>>"

async function findWorkspaceByName() {
    let response = await fetch(`${tonicUrl}/api/Workspace/search?filters[name]=${encodeURIComponent(workspaceName)}`, {
        method: 'get',
        headers: { 'Authorization': `apikey ${apiKey}` },
    });

    const result = await response.json();
    const matches = result.records.filter(w => w.workspaceName === workspaceName);
    if (matches.length === 0) {
        throw new Error(`No workspace found with name: ${workspaceName}`);
    }
    if (matches.length > 1) {
        throw new Error(`Multiple workspaces found with name: ${workspaceName}`);
    }
    return matches[0].id;
}

async function generateData(workspaceId) {
    let response = await fetch(`${tonicUrl}/api/generateData/start?workspaceId=${workspaceId}&strictMode=RejectOnAllSchemaItems`, {
        method: 'post',
        headers: { 'Authorization': `apikey ${apiKey}` },
    });

    if(!response.ok) {
        throw new Error(await response.text());
    }

    const job = await response.json();

    return job.id;
}

findWorkspaceByName()
.then(workspaceId => generateData(workspaceId))
.then(jobId => console.log(`Job ${jobId} queued`));
```

{% endcode %}
{% endtab %}

{% tab title="Powershell" %}
{% code title="tonic\_generation.ps1" overflow="wrap" %}

```bash
# Note that our API does not guarantee backward compatibility.
# For the endpoints and parameters for your exact version, view the 
# Swagger API documentation that comes with your instance.
# If you use Structural Cloud, the API documentation is at:
# https://app.tonic.ai/apidocs/index.html

# Tested 2026.07.08 with Tonic API v2024.01.0

$apiKey = "<<STRUCTURAL API TOKEN>>"
$workspaceName = "<<STRUCTURAL WORKSPACE>>"
$tonicUrl = "https://<<STRUCTURAL HOSTNAME>>"

$headers = New-Object "System.Collections.Generic.Dictionary[[String],[String]]"
$headers.Add("Authorization", "apikey $apiKey")
$headers.Add("Accept", "application/json")

$searchResponse = Invoke-RestMethod "$tonicUrl/api/Workspace/search?filters[name]=$([uri]::EscapeDataString($workspaceName))" -Method 'GET' -Headers $headers -UseBasicParsing

$filteredWorkspaces = $searchResponse.records.Where({$_.workspaceName -eq $workspaceName})

if ($filteredWorkspaces.Count -eq 0)
{
    throw "No workspace found with name: $workspaceName"
}
if ($filteredWorkspaces.Count -gt 1)
{
    throw "Multiple workspaces found with name: $workspaceName"
}

$workspaceId = $filteredWorkspaces[0].id

try {
    $generateResponse = Invoke-RestMethod "$tonicUrl/api/generateData/start?workspaceId=$workspaceId&strictMode=RejectOnAllSchemaItems" -Method 'POST' -Headers $headers -UseBasicParsing
    $jobId = $generateResponse.id
    Write-Host "Job $jobId queued"
}
catch {
    $result = $_.Exception.Response.GetResponseStream()
    $reader = New-Object System.IO.StreamReader($result)
    $reader.BaseStream.Position = 0
    $reader.DiscardBufferedData()
    $responseBody = $reader.ReadToEnd();
    throw $responseBody
}

```

{% endcode %}
{% endtab %}

{% tab title="Bash" %}
{% code title="tonic\_generation.sh" overflow="wrap" %}

```bash
#!/bin/bash
# Note that our API does not guarantee backward compatibility.
# For the endpoints and parameters for your exact version, view the 
# Swagger API documentation that comes with your instance.
# If you use Structural Cloud, the API documentation is at:
# https://app.tonic.ai/apidocs/index.html

# Tested 2026.07.08 with Tonic API v2024.01.0

# This script requires jq to be installed

apikey="<<STRUCTURAL API TOKEN>>"
workspaceName="<<STRUCTURAL WORKSPACE>>"
tonicUrl="https://<<STRUCTURAL HOSTNAME>>"

searchResponse=$(curl -s --request GET "${tonicUrl}/api/Workspace/search?filters%5Bname%5D=${workspaceName}" -H "Authorization: apikey $apikey" -H "Accept: application/json")

workspaceId=$(echo $searchResponse | jq -r --arg name "$workspaceName" '.records[] | select(.workspaceName == $name) | .id')
if [ ${#workspaceId} != 36 ]
then
    echo "No workspace found with name: $workspaceName"
    exit 1
fi

generateResponse=$(curl -s --request POST "${tonicUrl}/api/generateData/start?workspaceId=${workspaceId}&strictMode=RejectOnAllSchemaItems" -H "Authorization: apikey $apikey" -H "Accept: application/json" -H "Content-Length: 0")
if [[ $generateResponse == *{* ]]
then
    jobId=$(echo $generateResponse | jq -r '.id')
    echo "Job $jobId queued"
else
    echo $generateResponse | tr -d '"'
    exit 1
fi

```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.tonic.ai/app/api/api-examples.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
