Generate structured output

The function ai.text.structuredCompletion can be used to generate structured output based on a textual input prompt and an output schema, represented as a Cypher map. It is similar to submitting a prompt to an LLM, but with the additional guarantee that the output conforms to the requested schema.

Signature for ai.text.structuredCompletion

Syntax

ai.text.structuredCompletion(prompt, schema, provider, configuration = {}) :: MAP

Description

Generate structured output as a map based on the specified prompt and JSON schema.

Inputs

Name

Type

Description

prompt

STRING

The prompt to generate output from.

schema

MAP

A map describing the JSON schema for the desired output.

provider

STRING

The identifier of the provider: 'Azure-OpenAI', 'Bedrock', 'OpenAI', 'VertexAI'.

configuration

MAP

Provider specific configuration, use CALL ai.text.structuredCompletion.providers() to find the configuration needed for each provider. You can specify additional vendor options by adding vendorOptions with a map of values that will be passed along in the request.

Returns

MAP

A structured map conforming to the provided schema.

Examples

Example 1. Cookie recipes

This example asks the model for cookie recipes, requesting the output as objects with properties name, description, and tastiness.

WITH
  {
    type: 'object',
    properties: {
      recipes: {
        type: 'array',
        maxItems: 5,
        minItems: 5,
        items: {
          type: 'object',
          properties: {
            name: {type: "string"},
            description: {type: "string"},
            tastiness: {type: "integer", minimum: 1, maximum: 5}
          },
          required: ["name", "description", "tastiness"],
          additionalProperties: false
        }
      }
    },
    required: ['recipes'],
    additionalProperties: false
  } AS schema,
  {
    token: $openaiToken,
    model: 'gpt-5-nano'
  } AS conf
RETURN
  ai.text.structuredCompletion(
    'Hello! Produce a list of 5 cookie recipes, with their name, description, and tastiness rating.',
    schema,
    'openai',
    conf
  ) AS result
WITH
  {
    type: 'object',
    properties: {
      recipes: {
        type: 'array',
        maxItems: 5,
        minItems: 5,
        items: {
          type: 'object',
          properties: {
            name: {type: "string"},
            description: {type: "string"},
            tastiness: {type: "integer", minimum: 1, maximum: 5}
          },
          required: ["name", "description", "tastiness"],
          additionalProperties: false
        }
      }
    },
    required: ['recipes'],
    additionalProperties: false
  } AS schema,
  {
    token: $azureopenaiToken,
    resource: $azureopenaiResource,
    model: 'gpt-5-mini'
  } AS conf
RETURN
  ai.text.structuredCompletion(
    'Hello! Produce a list of 5 cookie recipes, with their name, description, and tastiness rating.',
    schema,
    'azure-openai',
    conf
  ) AS result
WITH
  {
    type: 'object',
    properties: {
      recipes: {
        type: 'array',
        maxItems: 5,
        minItems: 5,
        items: {
          type: 'object',
          properties: {
            name: {type: "string"},
            description: {type: "string"},
            tastiness: {type: "integer", minimum: 1, maximum: 5}
          },
          required: ["name", "description", "tastiness"],
          additionalProperties: false
        }
      }
    },
    required: ['recipes'],
    additionalProperties: false
  } AS schema,
  {
    apiKey: $vertexaiToken,
    project: $vertexaiProject,
    region: $vertexaiRegion,
    model: 'gemini-2.5-flash-lite',
    publisher: 'google'
  } AS conf
RETURN
  ai.text.structuredCompletion(
    'Hello! Produce a list of 5 cookie recipes, with their name, description, and tastiness rating.',
    schema,
    'vertexai',
    conf
  ) AS result
WITH
  {
    type: 'object',
    properties: {
      recipes: {
        type: 'array',
        maxItems: 5,
        minItems: 5,
        items: {
          type: 'object',
          properties: {
            name: {type: "string"},
            description: {type: "string"},
            tastiness: {type: "integer", minimum: 1, maximum: 5}
          },
          required: ["name", "description", "tastiness"],
          additionalProperties: false
        }
      }
    },
    required: ['recipes'],
    additionalProperties: false
  } AS schema,
  {
    accessKeyId: $bedrockKey,
    secretAccessKey: $bedrockSecret,
    region: 'us-east-1',
    model: 'amazon.nova-micro-v1:0'
  } AS conf
RETURN
  ai.text.structuredCompletion(
    'Hello! Produce a list of 5 cookie recipes, with their name, description, and tastiness rating.',
    schema,
    'bedrock',
    conf
  ) AS result
result
{
  recipes: [
    {
      name: "Chocolate Chip Cookies",
      description: "Classic chewy cookies loaded with semisweet chocolate chips and vanilla.",
      tastiness: 1
    },
    {
      name: "Peanut Butter Cookies",
      description: "Soft, peanut-buttery cookies with a slightly salty edge and classic crisscross fork marks.",
      tastiness: 3
    },
    {
      name: "Oatmeal Raisin Cookies",
      description: "Hearty oats, plump raisins, and warm spices for a chewy, comforting bite.",
      tastiness: 5
    },
    {
      name: "Snickerdoodles",
      description: "Soft cookies rolled in cinnamon-sugar with a subtle tang from cream of tartar."
      tastiness: 5
    },
    {
      name: "Sugar Cookies",
      description: "Buttery, vanilla-forward cookies with a tender crumb—perfect for decorating.",
      tastiness: 3
    }
  ]
}
Example 2. Object classification

This example provides the model with a list of movie titles and plots, alongside a few movie genres, and asks to sort the movies into genres.

WITH
  {
    type: 'object',
    properties: {
      recipes: {
        type: 'array',
        maxItems: 5,
        minItems: 5,
        items: {
          type: 'object',
          properties: {
            name: {type: "string"},
            description: {type: "string"},
            tastiness: {type: "integer", minimum: 1, maximum: 5}
          },
          required: ["name", "description", "tastiness"],
          additionalProperties: false
        }
      }
    },
    required: ['recipes'],
    additionalProperties: false
  } AS schema,
  {
    token: $openaiToken,
    model: 'gpt-5-nano'
  } AS conf
RETURN
  ai.text.structuredCompletion(
    'Classify these films into their correct genres, using only the genres ['SciFi’, 'Horror’, 'Action’, 'Romance’, 'Drama’, 'Documentary’, 'Other’]. Films: ' + movies,
    schema,
    'openai',
    conf
  ) AS result
WITH
  {
    type: 'object',
    properties: {
      recipes: {
        type: 'array',
        maxItems: 5,
        minItems: 5,
        items: {
          type: 'object',
          properties: {
            name: {type: "string"},
            description: {type: "string"},
            tastiness: {type: "integer", minimum: 1, maximum: 5}
          },
          required: ["name", "description", "tastiness"],
          additionalProperties: false
        }
      }
    },
    required: ['recipes'],
    additionalProperties: false
  } AS schema,
  {
    token: $azureopenaiToken,
    resource: $azureopenaiResource,
    model: 'gpt-5-mini'
  } AS conf
RETURN
  ai.text.structuredCompletion(
    'Classify these films into their correct genres, using only the genres ['SciFi’, 'Horror’, 'Action’, 'Romance’, 'Drama’, 'Documentary’, 'Other’]. Films: ' + movies,
    schema,
    'azure-openai',
    conf
  ) AS result
WITH
  {
    type: 'object',
    properties: {
      recipes: {
        type: 'array',
        maxItems: 5,
        minItems: 5,
        items: {
          type: 'object',
          properties: {
            name: {type: "string"},
            description: {type: "string"},
            tastiness: {type: "integer", minimum: 1, maximum: 5}
          },
          required: ["name", "description", "tastiness"],
          additionalProperties: false
        }
      }
    },
    required: ['recipes'],
    additionalProperties: false
  } AS schema,
  {
    apiKey: $vertexaiToken,
    project: $vertexaiProject,
    region: $vertexaiRegion,
    model: 'gemini-2.5-flash-lite',
    publisher: 'google'
  } AS conf
RETURN
  ai.text.structuredCompletion(
    'Classify these films into their correct genres, using only the genres ['SciFi’, 'Horror’, 'Action’, 'Romance’, 'Drama’, 'Documentary’, 'Other’]. Films: ' + movies,
    schema,
    'vertexai',
    conf
  ) AS result
WITH
  {
    type: 'object',
    properties: {
      recipes: {
        type: 'array',
        maxItems: 5,
        minItems: 5,
        items: {
          type: 'object',
          properties: {
            name: {type: "string"},
            description: {type: "string"},
            tastiness: {type: "integer", minimum: 1, maximum: 5}
          },
          required: ["name", "description", "tastiness"],
          additionalProperties: false
        }
      }
    },
    required: ['recipes'],
    additionalProperties: false
  } AS schema,
  {
    accessKeyId: $bedrockKey,
    secretAccessKey: $bedrockSecret,
    region: 'us-east-1',
    model: 'amazon.nova-micro-v1:0'
  } AS conf
RETURN
  ai.text.structuredCompletion(
    'Classify these films into their correct genres, using only the genres ['SciFi’, 'Horror’, 'Action’, 'Romance’, 'Drama’, 'Documentary’, 'Other’]. Films: ' + movies,
    'bedrock',
    conf
  ) AS result
result
{
  movies: [
    {
      genre: "SciFi",
      movieTitles: ["Cowboy Bebop", "Black Mirror", "Inception", "Matrix, The", "Star Wars: Episode V - The Empire Strikes Back", "Battlestar Galactica"]
    },
    {
      genre: "Horror",
      movieTitles: []
    },
    {
      genre: "Action",
      movieTitles: ["Dark Knight, The", "The Good, the Bad and the Ugly, The", "Seven Samurai (Shichinin no samurai)"]
    },
    {
      genre: "Romance",
      movieTitles: ["Pride and Prejudice"]
    },
    {
      genre: "Drama",
      movieTitles: ["Band of Brothers", "Shawshank Redemption, The", "Decalogue, The (Dekalog)", "Godfather, The", "Godfather: Part II, The", "From the Earth to the Moon", "Lord of the Rings: The Fellowship of the Ring, The", "Lord of the Rings: The Return of the King, The", "Lord of the Rings: The Two Towers, The", "Fight Club", "12 Angry Men", "Schindler's List", "Pulp Fiction", "Berlin Alexanderplatz", "Lonesome Dove", "Harakiri (Seppuku)", "Tinker, Tailor, Soldier, Spy", "Forsyte Saga, The", "Forrest Gump", "Goodfellas", "City of God (Cidade de Deus)"]
    },
    {
      genre: "Documentary",
      movieTitles: ["Civil War, The", "Cosmos", "Frozen Planet", "Making a Murderer", "George Carlin: Jammin' in New York", "The Jinx: The Life and Deaths of Robert Durst", "Bill Hicks: Revelations", "Buster Keaton: A Hard Act to Follow", "George Carlin: Back in Town", "Bill Hicks: Relentless", "George Carlin: You Are All Diseased", "George Carlin: It's Bad for Ya!", "Power of Nightmares, The", "Concert for George, The", "Generation Kill", "Louis C.K.: Shameless"]
    },
    {
      genre: "Other",
      movieTitles: ["Fawlty Towers (1975: Hotel owner Basil Fawlty's incompetence, short fuse, and arrogance form a combination that ensures accidents and trouble are never far away.", "Dr. Horrible's Sing-Along Blog", "Operation 'Y' & Other Shurik's Adventures"]
    }
  ]
}
Example 3. Sentiment analysis

This example asks the model to classify reviews (either positive, negative, or neutral) and to provide a reson for its judgement.

WITH [
  "Extremely well-prepared and tasty lunch with stylish presentations. The salad buffet is well-stocked with various fine pasta salads, potato salads, etc.
The staff is friendly and the service is impeccable.",
  "The lunch menu looked nice and the food looked good when it arrived but unfortunately was completely tasteless. Can't give anything but a one when I factor in the expensive price point."
] AS reviewsList
WITH
  reduce(acc = '[', r IN reviewsList | acc + '"' + r + '"' + ', ') + ']' AS reviews,
  {token: $openaiToken, model: 'gpt-5-nano'} AS conf,
  {
    type: 'object',
    properties: {
      sentiments: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            sentiment: {type: "string", enum: ['positive', 'negative', 'neutral']},
            reason: {type: "string"}
          },
          required: ["sentiment", "reason"],
          additionalProperties: false
        }
      }
    },
    required: ['sentiments'],
    additionalProperties: false
  } AS schema,
  {
    token: $openaiToken,
    model: 'gpt-5-nano'
  } AS conf
RETURN
  ai.text.structuredCompletion(
    'Classify these films into their correct genres, using only the genres ['SciFi’, 'Horror’, 'Action’, 'Romance’, 'Drama’, 'Documentary’, 'Other’]. Films: ' + movies,
    schema,
    'openai',
    conf
  ) AS result
WITH [
  "Extremely well-prepared and tasty lunch with stylish presentations. The salad buffet is well-stocked with various fine pasta salads, potato salads, etc.
The staff is friendly and the service is impeccable.",
  "The lunch menu looked nice and the food looked good when it arrived but unfortunately was completely tasteless. Can't give anything but a one when I factor in the expensive price point."
] AS reviewsList
WITH
  reduce(acc = '[', r IN reviewsList | acc + '"' + r + '"' + ', ') + ']' AS reviews,
  {token: $openaiToken, model: 'gpt-5-nano'} AS conf,
  {
    type: 'object',
    properties: {
      sentiments: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            sentiment: {type: "string", enum: ['positive', 'negative', 'neutral']},
            reason: {type: "string"}
          },
          required: ["sentiment", "reason"],
          additionalProperties: false
        }
      }
    },
    required: ['sentiments'],
    additionalProperties: false
  } AS schema,
  {
    token: $azureopenaiToken,
    resource: $azureopenaiResource,
    model: 'gpt-5-mini'
  } AS conf
RETURN
  ai.text.structuredCompletion(
    'Classify these films into their correct genres, using only the genres ['SciFi’, 'Horror’, 'Action’, 'Romance’, 'Drama’, 'Documentary’, 'Other’]. Films: ' + movies,
    schema,
    'azure-openai',
    conf
  ) AS result
WITH [
  "Extremely well-prepared and tasty lunch with stylish presentations. The salad buffet is well-stocked with various fine pasta salads, potato salads, etc.
The staff is friendly and the service is impeccable.",
  "The lunch menu looked nice and the food looked good when it arrived but unfortunately was completely tasteless. Can't give anything but a one when I factor in the expensive price point."
] AS reviewsList
WITH
  reduce(acc = '[', r IN reviewsList | acc + '"' + r + '"' + ', ') + ']' AS reviews,
  {token: $openaiToken, model: 'gpt-5-nano'} AS conf,
  {
    type: 'object',
    properties: {
      sentiments: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            sentiment: {type: "string", enum: ['positive', 'negative', 'neutral']},
            reason: {type: "string"}
          },
          required: ["sentiment", "reason"],
          additionalProperties: false
        }
      }
    },
    required: ['sentiments'],
    additionalProperties: false
  } AS schema,
  {
    apiKey: $vertexaiToken,
    project: $vertexaiProject,
    region: $vertexaiRegion,
    model: 'gemini-2.5-flash-lite',
    publisher: 'google'
  } AS conf
RETURN
  ai.text.structuredCompletion(
    'Classify these films into their correct genres, using only the genres ['SciFi’, 'Horror’, 'Action’, 'Romance’, 'Drama’, 'Documentary’, 'Other’]. Films: ' + movies,
    schema,
    'vertexai',
    conf
  ) AS result
WITH [
  "Extremely well-prepared and tasty lunch with stylish presentations. The salad buffet is well-stocked with various fine pasta salads, potato salads, etc.
The staff is friendly and the service is impeccable.",
  "The lunch menu looked nice and the food looked good when it arrived but unfortunately was completely tasteless. Can't give anything but a one when I factor in the expensive price point."
] AS reviewsList
WITH
  reduce(acc = '[', r IN reviewsList | acc + '"' + r + '"' + ', ') + ']' AS reviews,
  {token: $openaiToken, model: 'gpt-5-nano'} AS conf,
  {
    type: 'object',
    properties: {
      sentiments: {
        type: 'array',
        items: {
          type: 'object',
          properties: {
            sentiment: {type: "string", enum: ['positive', 'negative', 'neutral']},
            reason: {type: "string"}
          },
          required: ["sentiment", "reason"],
          additionalProperties: false
        }
      }
    },
    required: ['sentiments'],
    additionalProperties: false
  } AS schema,
  {
    accessKeyId: $bedrockKey,
    secretAccessKey: $bedrockSecret,
    region: 'us-east-1',
    model: 'amazon.nova-micro-v1:0'
  } AS conf
RETURN
  ai.text.structuredCompletion(
    'Classify these films into their correct genres, using only the genres ['SciFi’, 'Horror’, 'Action’, 'Romance’, 'Drama’, 'Documentary’, 'Other’]. Films: ' + movies,
    'bedrock',
    conf
  ) AS result
result
{
  sentiments: [
    {
      reason: "Extremely well-prepared and tasty lunch with stylish presentations; well-stocked salad buffet; friendly staff and impeccable service.",
      sentiment: "positive"
    },
    {
      reason: "Lunch menu looked nice and the food appeared good, but it was completely tasteless; the expensive price point made it disappointing.",
      sentiment: "negative"
    }
  ]
}

Schema requirements

The schema argument is a Cypher map that must adhere to the JSON schema specifications of the chosen provider. Although most providers support standard JSON schema types (string, number, boolean, object, array), there are important differences in strictness and supported keywords.

Provider specifics
Provider Schema guidelines

OpenAI / Azure-OpenAI

Uses a strict subset of JSON Schema. See the OpenAI docs for more info.

  • All object properties must be listed as required.

  • All objects must specify additionalProperties: false.

  • Supported types include string, number, boolean, integer, object, array, enum, and anyOf.

Vertex AI

Uses a subset of the OpenAPI 3.0 Schema Object. See the VertexAI docs for more info.

  • Best suited for flat or moderately nested structures.

  • Ensure you check for specific keyword support (e.g., nullable).

Bedrock

Uses the Converse API’s tool definition format.

  • While more flexible, it is recommended to follow the OpenAPI 3.0 schema standard for maximum compatibility across different foundation models (e.g., Anthropic Claude vs. Amazon Nova).

If you provide a schema with unsupported keywords for a specific provider, the function will return an error from the provider’s API. Always start with a simple schema and increase complexity incrementally.

Providers

You can generate structured output via the following providers:

  • OpenAI (openai)

  • Azure OpenAI (azure-openai)

  • Google Vertex AI (vertexai)

  • Amazon Bedrock Models (bedrock)

OpenAI

OpenAI parameters
Name Type Default Description

model

STRING

-

Model ID (see OpenAI → Models).

token

STRING

-

OpenAI API key (see OpenAI → API Keys).

vendorOptions

MAP

{}

Optional vendor options that will be passed on as-is in the request to OpenAI (see OpenAI → Create a model response).

You can change OpenAI’s base URL (default: https://api.openai.com) via the genai.openai.baseurl setting. The change applies to all ai.text.* calls that use OpenAI. See Configuration settings → genai.openai.baseurl.

Azure OpenAI

Azure OpenAI parameters
Name Type Default Description

model

STRING

-

Model ID (see Azure → Azure OpenAI in Foundry Models).

resource

STRING

-

Azure resource name.

token

STRING

-

Azure OAuth2 bearer token.

vendorOptions

MAP

{}

Optional vendor options that will be passed on as-is in the request to Azure.

Google VertexAI

VertexAI parameters
Name Type Default Description

model

STRING

-

Model resource name (see Vertex AI → Model Garden).

project

STRING

-

Google cloud project ID.

region

STRING

-

Google cloud region (see Vertex AI → Locations).

publisher

STRING

'google'

Model publisher.

apiKey

STRING

-

Vertex AI API key.

token

STRING

-

Vertex API access token.

vendorOptions

MAP

{}

Optional vendor options that will be passed on as-is in the request to VertexAI (see Vertex AI → Method: models.generateContent).

Exactly one of apiKey or token must be provided.

Amazon Bedrock Models

This provider supports most Bedrock models and follows the Converse API.

Amazon Bedrock parameters
Name Type Default Description

model

STRING

-

Model ID or its ARN.

region

STRING

-

Amazon region (see Amazon Bedrock → Model Support).

accessKeyId

STRING

-

Amazon access key ID.

secretAccessKey

STRING

-

Amazon secret access key.

vendorOptions

MAP

{}

Optional vendor options that will be passed on as-is in the request to Bedrock (see Amazon Bedrock → Inference request parameters and response fields).