> [!WARNING]
> **Preview**: Using server prompt templates is a feature that's in Preview, which means that it isn't subject to any SLA or deprecation policy and could change in backwards-incompatible ways.

<br />

This guide applies to any capability that depends on multi-turn interactions,
including:

- [Multi-turn conversation (chat)](https://firebase.google.com/docs/ai-logic/server-prompt-templates/multi-turn-interactions.md.txt#chat), including text-output-only chat and
  iterative image editing

- [Function calling](https://firebase.google.com/docs/ai-logic/server-prompt-templates/multi-turn-interactions.md.txt#function-calling)

> [!NOTE]
> **Note:** Before using this guide about multi-turn interactions, review [Get started with server prompt templates](https://firebase.google.com/docs/ai-logic/server-prompt-templates/get-started.md.txt) so that you're familiar with how server prompt templates work in a "Hello World" scenario.

## High-level overview

For multi-turn interactions, the Firebase AI Logic SDKs manage the
state of the conversation. This applies when using server prompt templates, too.

The basic workflow for multi-turn interactions and server prompt templates is
fundamentally the same as for single-turn requests, with some important
differences:

1. Create the template using the guided UI in the
   [Firebase console](https://console.firebase.google.com/project/_/ailogic/templates?useAutoProject=true).

   For multi-turn interactions, you must add the
   `{{history}}` tag in the template's content,
   which tells the template where to inject the conversation turns managed by
   the client SDK.
2. Test the template in a real request using the testing experience in the
   Firebase console.

   For multi-turn interactions, the console testing experience can only help
   test the initial turn. You can test how subsequent turns (the history) are
   handled by using the template with your actual app.
3. Access the template from your app's code using `templateGenerativeModel`.

   For multi-turn interactions, you must use `startChat` and `sendMessage`
   (just like you do for multi-turn interactions when *not* using server prompt
   templates).

Note that for [function calling](https://firebase.google.com/docs/ai-logic/server-prompt-templates/multi-turn-interactions.md.txt#function-calling), there are a few more
differences, which are described in that section later on this page.

<br />

*** ** * ** ***

## Multi-turn conversation (chat)

If you haven't already, review the
[general guide for building multi-turn conversations (chat)](https://firebase.google.com/docs/ai-logic/chat.md.txt)
when *not* using server prompt templates.

> [!NOTE]
> **Note:** The instructions in this section can be used with any Gemini model that supports chat, including the Gemini Nano Banana models for iterative image editing.

### Basic format of a server prompt template

For Firebase AI Logic, the
[Firebase console](https://console.firebase.google.com/project/_/ailogic/templates?useAutoProject=true)
provides a guided UI for you to specify the template's frontmatter and contents.

Server prompt templates use a Dotprompt-based syntax and format.
For more details, see
[Template format, syntax, and examples](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples.md.txt).

The example template below shows the most important components for a template
when building a multi-turn conversation (chat). Note the addition of the
`{{history}}` tag in the template's content,
which tells the template where to inject the conversation turns managed by the
client SDK.

    ---
    model: 'gemini-3.8-flash'
    ---

    {{role "system"}}
    You help customers with their invoices, including answering questions or providing their invoices to them.
    If an invoice is requested, it must be a clearly structured invoice document that uses a tabular or clearly delineated list format for line items.

    {{history}}

### Use your template in code

|---|
| *Click your Gemini API provider to view provider-specific content and code on this page.* <button value="dev" default="">Gemini Developer API</button> <button value="vertex">Agent Platform Gemini API</button> |

The example client code below shows how to use the template in your code. Note
the use of `templateGenerativeModel` along with `startChat` and `sendMessage`
when building multi-turn interactions.

### Swift

```swift
For Swift, using server prompt templates with multi-turn interactions is **not yet** supported. Check back soon!
```

### Kotlin

```kotlin

// ...

// Initialize the Gemini Developer API backend service.
// Create a `TemplateGenerativeModel` instance.
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
                        .templateGenerativeModel()

// Start a chat session with a template.
val chatSession = model.startChat(
  // Specify your template ID.
  templateId= "my-chat-template-v1-0-0",
  inputs = emptyMap()
)

// Send messages.
// The template's system instructions and model config apply to every turn automatically.
// The SDK automatically manages the state of the conversation.
val response = chatSession.sendMessage(
  content("user") { text("I need a copy of my invoice.") }
)

val text = response.text
println(text)

```

### Java

```java

// ...

// Initialize the Gemini Developer API backend service
// Create a `TemplateGenerativeModel` instance.
TemplateGenerativeModel templateModel = FirebaseAI.getInstance(GenerativeBackend.googleAI())
    .templateGenerativeModel();
// Initialize TemplateChat with history and inputs
TemplateChat templateChat = templateModel.startChat(
    // Specify your template ID.
    "my-chat-template-v1-0-0",
    Map.of(),
    Collections.emptyList()
);
TemplateChatFutures chatFutures = TemplateChatFutures.from(templateChat);

// Send messages.
// The template's system instructions and model config apply to every turn automatically.
// The SDK automatically manages the state of the conversation.
Content prompt = new Content.Builder().addText("I need a copy of my invoice.").build();
ListenableFuture responseFuture = chatFutures.sendMessage(prompt);

Futures.addCallback(responseFuture, new FutureCallback() {
  @Override
  public void onSuccess(GenerateContentResponse result) {
    System.out.println("Response: " + result.getText());
  }

  @Override
  public void onFailure(Throwable t) {
    t.printStackTrace();
  }
}, executor);

```

### Web

```javascript

// ...

// Initialize the Gemini Developer API backend service.
const ai = getAI(app, { backend: new GoogleAIBackend() });

// Create a `TemplateGenerativeModel` instance.
const model = getTemplateGenerativeModel(ai);

// Start a chat session with a template.
const chatSession = model.startChat({
  // Specify your template ID.
  templateId: 'my-chat-template-v1-0-0',
  templateVariables: {},
});

// Send messages.
// The template's system instructions and model config apply to every turn automatically.
// The SDK automatically manages the state of the conversation.
const result = await chatSession.sendMessage("I need a copy of my invoice.");

const text = result.response.text();
console.log(text);

```

### Dart

```dart

// ...

// Initialize the Gemini Developer API backend service.
// Create a `TemplateGenerativeModel` instance.
final model = FirebaseAI.googleAI().templateGenerativeModel();

// Start a chat session with a template.
final chatSession = model.startChat(
  // Specify your template ID.
  'my-chat-template-v1-0-0',
  inputs: {},
);

// Send messages.
// The template's system instructions and model config apply to every turn automatically.
// The SDK automatically manages the state of the conversation.
final response = await chatSession.sendMessage(
  Content.text('I need a copy of my invoice.'),
);

final text = response.text;
print(text);

```

### Unity

```c#

// ...

// Initialize the Gemini Developer API backend service.
var firebaseAI = FirebaseAI.GetInstance(FirebaseAI.Backend.GoogleAI());

// Create a `TemplateGenerativeModel` instance.
var model = firebaseAI.GetTemplateGenerativeModel();

// Start a chat session with a template.
var chatSession = model.StartChat(
    // Specify your template ID.
    "my-chat-template-v1-0-0"
);

// Send messages.
// The template's system instructions and model config apply to every turn automatically.
// The SDK automatically manages the state of the conversation.
try
{
   var response = await chatSession.SendMessageAsync(ModelContent.Text("I need a copy of my invoice."));
   Debug.Log($"Response Text: {response.Text}");
}
catch (Exception e) {
  Debug.LogError($"An error occurred: {e.Message}");
}

```

> [!IMPORTANT]
> **Important:** We strongly recommend [using Firebase Remote Config with server prompt templates](https://firebase.google.com/docs/ai-logic/server-prompt-templates/versioning-with-remote-config.md.txt) so that you can more easily change the template ID and other values in your request.

<br />

*** ** * ** ***

## Function calling

If you haven't already, review the general guide for
[function calling](https://firebase.google.com/docs/ai-logic/function-calling.md.txt)
when *not* using server prompt templates. This guide about using server prompt
templates assumes that you understand how function calling works generally.
**Important** : When using function calling with server prompt templates, you need to decide whether you want to define the function schema in the template or in the client code.


For functions with basic schema, defining the schema in the template might be
preferable. However, for more complex schema, you might find that defining the
schema in client code is easier and keeps the schema close to the function
itself.


If a function's schema is provided in the client code, it
***will override*** any schema specified in the template.


**The first example in this section shows how to define schema in the
template** . Later on the page, find an example template and client code
for
[defining
schema in client code](https://firebase.google.com/docs/ai-logic/server-prompt-templates/multi-turn-interactions#function-calling-schema-defined-in-code).

### Basic format of a server prompt template

For Firebase AI Logic, the
[Firebase console](https://console.firebase.google.com/project/_/ailogic/templates?useAutoProject=true)
provides a guided UI for you to specify the template's frontmatter and contents.

Server prompt templates use a Dotprompt-based syntax and format.
For more details, see
[Template format, syntax, and examples](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples.md.txt).

The example template below shows the most important components for a template
when using function calling. Note the following:

- In the template's frontmatter, list the functions that the model has access
  to by providing function declarations in the `tools` object.

  > [!IMPORTANT]
  > **Important:** If a function isn't listed in the template, then the model doesn't have access to it.

  - Define the `name` *(required)* and the `description` *(optional)* for
    each function that the model has access to.

  - Define the schema for each function that the model has access to.

    This example template below assumes that you're defining function schemas
    in the template. However, you can instead provide the function's schema in
    the client code. Schema defined in client code ***will override*** any
    schema defined in the template. Later on this page, find an example of a
    template and client code for
    [defining schema in client code](https://firebase.google.com/docs/ai-logic/server-prompt-templates/multi-turn-interactions.md.txt#function-calling-schema-defined-in-code).
- In the template's content, add the
  `{{history}}` tag, which tells the template
  where to inject the conversation turns managed by the client SDK.

**Example template with function schema defined in template**

    ---
    model: gemini-3.8-flash
    tools:
      - name: fetchWeather
        description: Get the weather conditions for a specific city on a specific date.
        input:
          schema:
            location(object, The name of the city and its state for which to get the weather. Only cities in the USA are supported.):
              city: string, The city of the location.
              state: string, The state of the location.
            date: string, The date for which to get the weather. Date must be in the format YYYY-MM-DD.

    ---

    What was the weather like in Boston, Massachusetts on 10/17 in year 2024?

    {{history}}

### Use your template in code

|---|
| *Click your Gemini API provider to view provider-specific content and code on this page.* <button value="dev" default="">Gemini Developer API</button> <button value="vertex">Agent Platform Gemini API</button> |

The example client code below shows how to use the template in your code.
Note the following:

- Use `templateGenerativeModel` along with `startChat` and `sendMessage` when
  using multi-turn interactions.

- During initialization of the model in your client code, do ***not*** list
  the functions that the model has access to. Instead, functions must be
  listed in the `tools` object of the template's frontmatter (see above).

- This example client code below assumes that you're defining function schemas
  in the template. If you instead decide to define schema in your client code,
  it ***will override*** the template-defined schema. Later on this page, see
  an example template and client code for
  [defining schema in client code](https://firebase.google.com/docs/ai-logic/server-prompt-templates/multi-turn-interactions.md.txt#function-calling-schema-defined-in-code).

- Check whether the model returns a function call as part of fulfilling a
  request. If it does, your app needs to execute the local logic and then send
  the result back to the model.

**Example client code with function schema defined in template**

### Swift

```swift
For Swift, using server prompt templates with multi-turn interactions is **not yet** supported. Check back soon!
```

### Kotlin

```kotlin

// ...

// Initialize the Gemini Developer API backend service.
// Create a `TemplateGenerativeModel` instance.
val model = Firebase.ai(backend = GenerativeBackend.googleAI())
    .templateGenerativeModel()

// Start a chat session with a template that has functions listed as tools.
val chatSession = model.startChat(
    // Specify your template ID
    templateId = "my-function-calling-template-v1-0-0",
    inputs = emptyMap()
)

// Send a message that might trigger a function call.
val response = chatSession.sendMessage(
    content("user") { text(userMessage) }
)

// When the model responds with one or more function calls, invoke the function(s).
// Note that this is the same as when *not* using server prompt templates.
val functionCalls = response.functionCalls
val fetchWeatherCall = functionCalls.find { it.name == "fetchWeather" }

// Forward the structured input data from the model to the hypothetical external API.
val functionResponse = fetchWeatherCall?.let {
  // Alternatively, if your `Location` class is marked as @Serializable, you can use
  // val location = Json.decodeFromJsonElement(it.args["location"]!!)
  val location = Location(
      it.args["location"]!!.jsonObject["city"]!!.jsonPrimitive.content,
      it.args["location"]!!.jsonObject["state"]!!.jsonPrimitive.content
  )
  val date = it.args["date"]!!.jsonPrimitive.content
  fetchWeather(location, date)
}

```

### Java

```java
// ...


// Initialize the Gemini Developer API backend service.
// Create a `TemplateGenerativeModel` instance.
TemplateGenerativeModel model = FirebaseAI.getInstance(GenerativeBackend.googleAI())
    .templateGenerativeModel();


// Start a chat session with a template that has functions listed as tools.
TemplateChat chatSession = model.startChat(
    // Specify your template ID.
    "my-function-calling-template-v1-0-0",
    Map.of(), // Inputs
    List.of() // History
);
TemplateChatFutures chatFutures = TemplateChatFutures.from(chatSession);

// Send a message that might trigger a function call.
Content prompt = new Content.Builder().addText(userMessage).build();
ListenableFuture responseFuture = chatFutures.sendMessage(prompt);

Futures.addCallback(responseFuture, new FutureCallback() {
  @Override
  public void onSuccess(GenerateContentResponse result) {
    // When the model responds with one or more function calls, invoke the function(s).
    // Note that this is the same as when *not* using server prompt templates.
    for (FunctionCallPart callPart : result.getFunctionCalls()) {
      if ("fetchWeather".equals(callPart.getName())) {
        // Forward the structured input data from the model to the hypothetical external API.
        JsonObject location = (JsonObject) callPart.getArgs().get("location");
        String city = ((JsonPrimitive) location.get("city")).getContent();
        String state = ((JsonPrimitive) location.get("state")).getContent();
        String date = ((JsonPrimitive) callPart.getArgs().get("date")).getContent();
        Object response = fetchWeather(city, state, date);
      }
    }
  }

  @Override
  public void onFailure(Throwable t) {
    t.printStackTrace();
  }
}, executor);
```

### Web

```javascript

// ...

// Initialize the Gemini Developer API backend service.
const ai = getAI(app, { backend: new GoogleAIBackend() });

// Create a `TemplateGenerativeModel` instance.
const model = getTemplateGenerativeModel(ai);

// Start a chat session with a template that has functions listed as tools.
const chatSession = model.startChat({
  // Specify your template ID
  templateId: 'my-function-calling-template-v1-0-0',
  templateVariables: {},
});

// Send a message that might trigger a function call.
const result = await chatSession.sendMessage(userMessage);

// When the model responds with one or more function calls, invoke the function(s).
// Note that this is the same as when *not* using server prompt templates.
const functionCalls = result.response.functionCalls();
let functionCall;
let functionResult;

if (functionCalls.length > 0) {
  for (const call of functionCalls) {
    if (call.name === "fetchWeather") {
      // Forward the structured input data prepared by the model
      // to the hypothetical external API.
      functionResult = await fetchWeather(call.args);
      functionCall = call;
    }
  }
}

```

### Dart

```dart

// ...

// Initialize the Gemini Developer API backend service.
// Create a `TemplateGenerativeModel` instance.
final model = FirebaseAI.googleAI().templateGenerativeModel();

// Start a chat session with a template that has functions listed as tools.
var chatSession = model.startChat(
    // Specify your template ID
    'my-function-calling-template-v1-0-0',
    inputs: {},
);

// Send a message that might trigger a function call.
var response = await chatSession.sendMessage(
    Content.text(userMessage),
);

// Check if the model wants to call a function.
// Note that this is the same as when *not* using server prompt templates.
final functionCalls = response?.functionCalls.toList();
// When the model responds with one or more function calls, invoke the function(s).
if (functionCalls != null && functionCalls.isNotEmpty) {
  for (final functionCall in functionCalls) {
    if (functionCall.name == 'fetchWeather') {
      Map<String, dynamic> location =
          functionCall.args['location']! as Map<String, dynamic>;
      var date = functionCall.args['date']! as String;
      var city = location['city'] as String;
      var state = location['state'] as String;
      final functionResult =
          await fetchWeather(Location(city, state), date);
      // Send the response to the model so that it can use the result to
      // generate text for the user.
      response = await chatSession.sendMessage(
        Content.functionResponse(functionCall.name, functionResult),
      );
    }
  }
}

```

### Unity

```c#

// ...

// Initialize the Gemini Developer API backend service.
var firebaseAI = FirebaseAI.GetInstance(FirebaseAI.Backend.GoogleAI());

// Create a `TemplateGenerativeModel` instance.
var model = firebaseAI.GetTemplateGenerativeModel();

// Start a chat session with a template that has functions listed as tools.
var chatSession = model.StartChat(
    // Specify your template ID
    "my-function-calling-template-v1-0-0"
);

try
{
   // Send a message that might trigger a function call.
   var response = await chatSession.SendMessageAsync(ModelContent.Text(userMessage));
   var functionResponses = new List();

  // When the model responds with one or more function calls, invoke the function(s).
  // Note that this is the same as when *not* using server prompt templates.
  foreach (var functionCall in response.FunctionCalls) {
    if (functionCall.Name == "fetchWeather") {
      // TODO(developer): Handle invalid arguments.
      var location = functionCall.Args["location"] as Dictionary<string, object>;
      var city = location["city"] as string;
      var state = location["state"] as string;
      var date = functionCall.Args["date"] as string;

      functionResponses.Add(ModelContent.FunctionResponse(
        name: functionCall.Name,
        // Forward the structured input data prepared by the model
        // to the hypothetical external API.
        response: FetchWeather(city: city, state: state, date: date)
      ));
    }
    // TODO(developer): Handle other potential function calls, if any.
  }

  // Send the function responses back to the model.
  var functionResponseResult = await chatSession.SendMessageAsync(functionResponses);
}
catch (Exception e) {
  Debug.LogError($"An error occurred: {e.Message}");
}

```

> [!IMPORTANT]
> **Important:** We strongly recommend [using Firebase Remote Config with server prompt templates](https://firebase.google.com/docs/ai-logic/server-prompt-templates/versioning-with-remote-config.md.txt) so that you can more easily change the template ID and other values in your request.

<br />

### Function calling - define schema in client code

Make sure to review the sections above about how function calling works with
server prompt templates (in particular, the use of the
`{{history}}` tag in the content of the
template). This section here provides an example template and client code if you
want to define your function schema in client code (instead of in the template).

Note the following about defining function schema in client code:

- If you define a function's schema in your client code (as shown in the
  example below), the client-side schema ***will override*** any
  template-defined schema for that function.

- To define the function schema in client code, write the function declaration
  and then **provide the declaration in `startChat`** ,
  *not during model initialization* (which is what you do when *not* using
  server prompt templates).

- Even though the function declaration specifies a `name`, the template must
  still list the functions that you want the model to have access to. The
  `name` in the template must match the `name` in the client code.

**Example template with function schema defined in client code**

    ---
    model: gemini-3.8-flash
    tools:
      - name: fetchWeather
        description: Get the weather conditions for a specific city on a specific date.
    ---

    What was the weather like in Boston, Massachusetts on 10/17 in year 2024, formatted in CELSIUS?

    {{history}}

**Example client code with function schema defined in client code**   

*(for details omitted from this example, see the
[example client code above](https://firebase.google.com/docs/ai-logic/server-prompt-templates/multi-turn-interactions.md.txt#function-calling-use-template-in-code))*

### Swift

```swift
For Swift, using server prompt templates with multi-turn interactions is **not yet** supported. Check back soon!
```

### Kotlin

```kotlin
// ...

// Initialize your desired Gemini API backend service.
// Create a `TemplateGenerativeModel` instance.
...

// Define the schema for any functions listed in your template.
val fetchWeatherTool = functionDeclarations(
    functionDeclarations = listOf(
        FunctionDeclaration(
            name = "fetchWeather",
            description = "Returns the weather for a given location at a given time",
            parameters = mapOf(
                "location" to Schema.obj(
                    description = "The name of the city and its state for which to get the weather. Only cities in the USA are supported.",
                    properties = mapOf(
                        "city" to Schema.string(
                            description = "The city of the location."
                        ),
                        "state" to Schema.string(
                            description = "The state of the location."
                        ),
                        "zipCode" to Schema.string(
                            description = "Optional zip code of the location.",
                            nullable = true
                        )
                    ),
                    optionalProperties = listOf("zipCode")
                ),
                "date" to Schema.string(
                    description = "The date for which to get the weather. Date must be in the format: YYYY-MM-DD."
                ),
                "unit" to Schema.enumeration(
                    description = "The temperature unit.",
                    values = listOf("CELSIUS", "FAHRENHEIT"),
                    nullable = true
                )

            ),
            optionalParameters = listOf("unit"),
        )
    )
)

// Start a chat session with a template that has functions listed as tools.
var chatSessionWithSchemaOverride = model.startChat(
    // Specify your template ID.
    templateId = "my-function-calling-template-with-no-function-schema-v1-0-0",
    // In `startChat`, provide the schema for any functions listed in your template.
    // This client-side schema will override any schema defined in the template.
    tools = listOf(fetchWeatherTool)
)

// Send a message that might trigger a function call.
...

// When the model responds with one or more function calls, invoke the function(s).
// Note that this is the same as when *not* using server prompt templates.
...

// Forward the structured input data from the model to the hypothetical external API.
...
```

### Java

```java
TemplateFunctionDeclaration tool = new TemplateFunctionDeclaration(
    "fetchWeather", // Name
    JsonSchema.obj( // Parameters
        Map.of(
            "location", JsonSchema.obj(
                Map.of(
                    "city", JsonSchema.string(
                        "The city of the location."
                    ),
                    "state", JsonSchema.string(
                        "The state of the location."
                    ),
                    "zipCode", JsonSchema.string(
                        "Optional zip code of the location",
                        true // Nullable
                    )
                ),
                List.of("zipCode"),
                ""
            ),
            "date", JsonSchema.string(
                "The date for which to get the weather. Date must be in the format: YY-MM-DD."
            ),
            "unit", JsonSchema.enumeration(
                List.of("CELSIUS", "FAHRENHEIT"),
                "The temperature unit.",
                true // Nullable
            )
        )
    ),
    JsonSchema.string(
        "A description of the current weather."
    )
);

// Initialize the Gemini Developer API backend service.
// Create a `TemplateGenerativeModel` instance.
TemplateGenerativeModel templateModel = FirebaseAI.getInstance(GenerativeBackend.googleAI())
    .templateGenerativeModel(
        new RequestOptions(),
        List.of(TemplateTool.functionDeclarations(List.of(tool), List.of()))
    );

// In `startChat`, provide the schema for any functions listed in your template.
// This client-side schema will override any schema defined in the template.
TemplateChat chat = templateModel.startChat(
    // Specify your template ID.
    "my-function-calling-template-with-no-function-schema-v1-0-0",
    Map.of(),
    List.of()
);
TemplateChatFutures futures = TemplateChatFutures.from(chat);

// Send a message that might trigger a function call.
...

// When the model responds with one or more function calls, invoke the function(s).
// Note that this is the same as when *not* using server prompt templates.
...

// Forward the structured input data from the model to the hypothetical external API.
...
```

### Web

```javascript
// ...

// Initialize your desired Gemini API backend service.
...

// Create a `TemplateGenerativeModel` instance.
...

// Start a chat session with a template that has functions listed as tools.
const chatSessionWithSchemaOverride = model.startChat({
  // Specify your template ID.
  templateId: 'my-function-calling-template-with-no-function-schema-v1-0-0',
  templateVariables: {},
  // In `startChat`, provide the schema for any functions listed in your template.
  // This client-side schema will override any schema defined in the template.
  tools: [
    {
      functionDeclarations: [
        {
          name: "fetchWeather",
          parameters: {
            type: SchemaType.OBJECT,
            properties: {
              location: {
                type: SchemaType.OBJECT,
                description: "The name of the city and its state for which to get the weather. Only cities in the USA are supported.",
                properties: {
                  city: {
                    type: SchemaType.STRING,
                    description: "The city of the location."
                  },
                  state: {
                    type: SchemaType.STRING,
                    description: "The state of the location."
                  },
                  zipCode: {
                    type: SchemaType.INTEGER,
                    description: "Optional zip code of the location.",
                    nullable: true
                  },
                },
                required: ["city", "state"],
              },
              date: {
                type: SchemaType.STRING,
                description: "The date for which to get the weather. Date must be in the format: YYYY-MM-DD.",
              },
              unit: {
                type: SchemaType.STRING,
                description: "The temperature unit.",
                enum: ["CELSIUS", "FAHRENHEIT"],
                nullable: true,
              },
            },
            required: ["location", "date"],
          },
        },
      ],
    }
  ],
});

// Send a message that might trigger a function call.
...

// When the model responds with one or more function calls, invoke the function(s).
// Note that this is the same as when *not* using server prompt templates.
...
```

### Dart

```dart
// ...

// Initialize your desired Gemini API backend service.
// Create a `TemplateGenerativeModel` instance.
...

// Start a chat session with a template that has functions listed as tools.
final chatSessionWithSchemaOverride = model?.startChat(
      // Specify your template ID.
      'my-function-calling-template-with-no-function-schema-v1-0-0',
      inputs: {},
      // In `startChat`, provide the schema for any functions listed in your template.
      // This client-side schema will override any schema defined in the template.
      tools: [
        TemplateTool.functionDeclarations(
          [
            TemplateFunctionDeclaration(
              'fetchWeather',
              parameters: {
                'location': JSONSchema.object(
                  description:
                      'The name of the city and its state for which to get '
                      'the weather. Only cities in the USA are supported.',
                  properties: {
                    'city': JSONSchema.string(
                      description: 'The city of the location.',
                    ),
                    'state': JSONSchema.string(
                      description: 'The state of the location.',
                    ),
                    'zipCode': JSONSchema.integer(
                      description: 'Optional zip code of the location.',
                      nullable: true,
                    ),
                  },
                  optionalProperties: ['zipCode'],
                ),
                'date': JSONSchema.string(
                  description: 'The date for which to get the weather. '
                      'Date must be in the format: YYYY-MM-DD.',
                ),
                'unit': JSONSchema.enumString(
                  enumValues: ['CELSIUS', 'FAHRENHEIT'],
                  description: 'The temperature unit.',
                  nullable: true,
                ),
              },
              optionalParameters: ['unit'],
            ),
          ],
        ),
      ],
    );

// Send a message that might trigger a function call.
...

// Check if the model wants to call a function.
// Note that this is the same as when *not* using server prompt templates.
...
```

### Unity

```c#
// ...

// Initialize your chosen Gemini API backend service.
...

// Create a `TemplateGenerativeModel` instance.
...

// Define the schema for any functions listed in your template.
var fetchWeatherTool = new TemplateTool.FunctionDeclaration(
    name: "fetchWeather",
    parameters: new Dictionary<string, JsonSchema>() {
        { "location", JsonSchema.Object(
            description: "The name of the city and its state for which to get the weather. Only cities in the USA are supported.",
            properties: new Dictionary<string, JsonSchema>() {
                { "city", JsonSchema.String(description: "The city of the location.") },
                { "state", JsonSchema.String(description: "The state of the location.") },
                { "zipCode", JsonSchema.Int(description: "Optional zip code of the location.", nullable: true) }
            },
            optionalProperties: new[] { "zipCode" })
        },
        { "date", JsonSchema.String(description: "The date for which to get the weather. Date must be in the format: YYYY-MM-DD.")},
        { "unit", JsonSchema.Enum(
            values: new[] { "CELSIUS", "FAHRENHEIT" },
            description: "The temperature unit.",
            nullable: true)
        }
    },
    optionalParameters: new[] { "unit" }
);

// Start a chat session with a template that has functions listed as tools.
var chatSessionWithSchemaOverride = model.StartChat(
    // Specify your template ID.
    templateId: "my-function-calling-template-with-no-function-schema-v1-0-0",
    // In `startChat`, provide the schema for any functions listed in your template.
    // This client-side schema will override any schema defined in the template.
    tools: new[] { fetchWeatherTool }
);

try
{
   // Send a message that might trigger a function call.
   ...

  // When the model responds with one or more function calls, invoke the function(s).
  // Note that this is the same as when *not* using server prompt templates.
  ...
}

// ...
```

<br />

*** ** * ** ***

## What's next?

- Learn about
  [best practices and considerations](https://firebase.google.com/docs/ai-logic/server-prompt-templates/best-practices-and-considerations.md.txt)
  for using server prompt templates.

- Learn details about the
  [template format and syntax, along with examples](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples.md.txt).

- [Manage templates](https://firebase.google.com/docs/ai-logic/server-prompt-templates/manage-templates.md.txt),
  including editing, locking, and version control.