This recipe provides an example of Completions API tool use for structured output. Instead of receiving unstructured text responses, you can force the AI to return predictable, machine-readable data that your application can easily parse and use. We’ll build a goal-setting assistant that takes a user’s goal in plain English and returns a structured growth plan with actionable steps and timelines.

Prerequisites

Before starting, ensure you have:
The Completions API with tool use requires Bearer token authentication. If you haven’t set up authentication yet, follow the Authentication Tutorial to learn how to exchange your credentials for access tokens and manage token expiration.

Step 1: Define Your Tool Schema

The first step is to define a function schema that describes the structured output you want. This tells the AI exactly what format to return:
{
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "create_growth_plan",
        "description": "Creates a structured personal growth plan with a title and a series of actionable steps.",
        "parameters": {
          "type": "object",
          "properties": {
            "goal_title": {
              "type": "string",
              "description": "A concise, encouraging title for the user's goal."
            },
            "steps": {
              "type": "array",
              "description": "A list of concrete steps the user should take.",
              "items": {
                "type": "object",
                "properties": {
                  "step_number": { "type": "integer" },
                  "action": {
                    "type": "string",
                    "description": "The specific, actionable task for this step."
                  },
                  "timeline": {
                    "type": "string",
                    "description": "A suggested timeframe for this step (e.g., 'Week 1-2')."
                  }
                },
                "required": ["step_number", "action", "timeline"]
              }
            }
          },
          "required": ["goal_title", "steps"]
        }
      }
    }
  ]
}

Step 2: Make the API Call

Now make the API request with the tool definition and set tool_choice: "required" to force the AI to use your tool:
{
  "model": "us.anthropic.claude-sonnet-4-20250514-v1:0",
  "messages": [
    {
      "role": "user",
      "content": "I want to grow in my faith."
    }
  ],
  "tools": [
    // ... The tool definition from Step 1 goes here ...
  ],
  "tool_choice": "required"
}

Example Response

The API will return structured data in the tool_calls array:
{
  "id": "chatcmpl-ecc49558",
  "choices": [
    {
      "finish_reason": "tool_calls",
      "index": 0,
      "message": {
        "content": null,
        "role": "assistant",
        "tool_calls": [
          {
            "id": "tooluse_c0lmjtOJSlOYQZPBsp4biQ",
            "function": {
              "arguments": "{\"goal_title\": \"Growing Deeper in Faith\", \"steps\": [{\"step_number\": 1, \"action\": \"Establish a consistent daily quiet time with God through prayer and Bible reading, starting with 10-15 minutes each morning\", \"timeline\": \"Week 1-2\"}, {\"step_number\": 2, \"action\": \"Choose a Bible reading plan or devotional to provide structure for your study time\", \"timeline\": \"Week 2-3\"}, {\"step_number\": 3, \"action\": \"Find a local church community or small group where you can worship, learn, and build relationships with other believers\", \"timeline\": \"Week 3-4\"}, {\"step_number\": 4, \"action\": \"Begin journaling your prayers, thoughts, and insights from Scripture to track your spiritual growth\", \"timeline\": \"Week 4-5\"}, {\"step_number\": 5, \"action\": \"Look for opportunities to serve others in your community or church as a way to live out your faith\", \"timeline\": \"Month 2\"}, {\"step_number\": 6, \"action\": \"Seek out a mentor or accountability partner who can encourage you and help you grow in your walk with God\", \"timeline\": \"Month 2-3\"}]}",
              "name": "create_growth_plan"
            },
            "type": "function"
          }
        ]
      }
    }
  ],
  "created": 1755118870,
  "model": "us.anthropic.claude-sonnet-4-20250514-v1:0",
  "object": "chat.completion",
  "usage": {
    "completion_tokens": 391,
    "prompt_tokens": 1631,
    "total_tokens": 2022
  }
}
Notice how the arguments field contains a JSON string that matches your tool schema perfectly!

Complete Examples

The following examples combine token retrieval, expiration checking, making the API call with tool use, and parsing the structured response into a complete, runnable script for each language. You’ll want to first set up your environment variables in either an .env file:
GLOO_CLIENT_ID=YOUR_CLIENT_ID
GLOO_CLIENT_SECRET=YOUR_CLIENT_SECRET
Or export them in your shell for Go and Java:
export GLOO_CLIENT_ID="your_actual_client_id_here"
export GLOO_CLIENT_SECRET="your_actual_client_secret_here"
import requests
import time
import json
import os
from dotenv import load_dotenv

# Load environment variables from .env file
load_dotenv()

# --- Configuration ---
# It's recommended to load credentials from environment variables
CLIENT_ID = os.getenv("GLOO_CLIENT_ID", "YOUR_CLIENT_ID")
CLIENT_SECRET = os.getenv("GLOO_CLIENT_SECRET", "YOUR_CLIENT_SECRET")
TOKEN_URL = "https://platform.ai.gloo.com/oauth2/token"
API_URL = "https://platform.ai.gloo.com/ai/v1/chat/completions"

# --- State Management ---
# In a real application, you would persist this token information
access_token_info = {}

def get_access_token():
    """Retrieves a new access token."""
    headers = {"Content-Type": "application/x-www-form-urlencoded"}
    data = {"grant_type": "client_credentials", "scope": "api/access"}
    response = requests.post(TOKEN_URL, headers=headers, data=data, auth=(CLIENT_ID, CLIENT_SECRET))
    response.raise_for_status()
    token_data = response.json()
    token_data['expires_at'] = int(time.time()) + token_data['expires_in']
    return token_data

def is_token_expired(token_info):
    """Checks if the token is expired or close to expiring."""
    if not token_info or 'expires_at' not in token_info:
        return True
    return time.time() > (token_info['expires_at'] - 60)

def create_goal_setting_request(user_goal):
    """Creates a goal-setting request with tool use."""
    global access_token_info
    if is_token_expired(access_token_info):
        print("Token is expired or missing. Fetching a new one...")
        access_token_info = get_access_token()

    headers = {
        "Authorization": f"Bearer {access_token_info['access_token']}",
        "Content-Type": "application/json"
    }

    payload = {
        "model": "us.anthropic.claude-sonnet-4-20250514-v1:0",
        "messages": [{"role": "user", "content": user_goal}],
        "tools": [
            {
                "type": "function",
                "function": {
                    "name": "create_growth_plan",
                    "description": "Creates a structured personal growth plan with a title and a series of actionable steps.",
                    "parameters": {
                        "type": "object",
                        "properties": {
                            "goal_title": {
                                "type": "string",
                                "description": "A concise, encouraging title for the user's goal."
                            },
                            "steps": {
                                "type": "array",
                                "description": "A list of concrete steps the user should take.",
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "step_number": {"type": "integer"},
                                        "action": {
                                            "type": "string",
                                            "description": "The specific, actionable task for this step."
                                        },
                                        "timeline": {
                                            "type": "string",
                                            "description": "A suggested timeframe for this step (e.g., 'Week 1-2')."
                                        }
                                    },
                                    "required": ["step_number", "action", "timeline"]
                                }
                            }
                        },
                        "required": ["goal_title", "steps"]
                    }
                }
            }
        ],
        "tool_choice": "required"
    }

    response = requests.post(API_URL, headers=headers, json=payload)
    response.raise_for_status()
    return response.json()

def parse_growth_plan(api_response):
    """Parses the API response and extracts the structured growth plan."""
    try:
        tool_call = api_response['choices'][0]['message']['tool_calls'][0]
        function_args = json.loads(tool_call['function']['arguments'])
        return function_args
    except (KeyError, IndexError, json.JSONDecodeError) as e:
        raise ValueError(f"Failed to parse growth plan: {e}")

def display_growth_plan(growth_plan):
    """Displays the growth plan in a user-friendly format."""
    print(f"\n🎯 {growth_plan['goal_title']}")
    print("=" * (len(growth_plan['goal_title']) + 4))

    for step in growth_plan['steps']:
        print(f"\n{step['step_number']}. {step['action']}")
        print(f"   ⏰ Timeline: {step['timeline']}")

# --- Main Execution ---
if __name__ == "__main__":
    try:
        user_goal = "I want to grow in my faith."
        print(f"Creating growth plan for: '{user_goal}'")

        # Make API call with tool use
        response = create_goal_setting_request(user_goal)

        # Parse the structured response
        growth_plan = parse_growth_plan(response)

        # Display the results
        display_growth_plan(growth_plan)

        # Also show raw JSON for developers
        print(f"\n📊 Raw JSON output:")
        print(json.dumps(growth_plan, indent=2))

    except requests.exceptions.HTTPError as err:
        print(f"An HTTP error occurred: {err}")
    except Exception as err:
        print(f"An error occurred: {err}")

Testing Your Implementation

To test any of the complete examples:
  1. Set up your environment variables with your actual Gloo AI credentials
  2. Install dependencies according to each language’s requirements
  3. Run the script and observe the structured output
The script will:
  • Automatically handle token retrieval and expiration
  • Make a tool-use API call with the goal “I want to grow in my faith”
  • Parse the JSON response into a structured format
  • Display the growth plan in a user-friendly format
  • Show the raw JSON for developers

Key Benefits

This approach provides several advantages over simple chat completions:
  1. Predictable Structure: The response always follows your defined schema
  2. Machine-Readable: Easy to parse and use in applications
  3. Type Safety: Clear data types for each field
  4. Validation: The API enforces your schema requirements
  5. Flexibility: Can adapt to any structured output needs

Next Steps

Now that you understand how to use tool use for structured output, consider exploring:
  1. Tool Use Guide - For more advanced tool use patterns
  2. Completions API - For additional API parameters
  3. Chat Tutorial - For integrating with stateful conversations
  4. Custom Schemas - Adapt this pattern for your specific use cases