<br />

| **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 />

For Firebase AI Logic, the Firebase console provides a guided UI for you
to specify the contents of a template.

Server prompt templates use a Dotprompt-based syntax and format. On this page,
you can find detailed descriptions of the template format and syntax, along with
examples for both [Gemini](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#gemini) and [Imagen](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#imagen).

Here are the most important components for an example request to a
Gemini model:  

    ---
    model: 'gemini-2.5-flash'
    ---

    {{role "system"}}
    All output must be a clearly structured invoice document.
    Use a tabular or clearly delineated list format for line items.

    {{role "user"}}
    Create an example customer invoice for a customer named {{customerName}}.

- The top section within the triple-dashes contains the model name as well as
  optionally any model configuration, input validation, or schema you want to
  send in the request. It's written as key-value pairs and is commonly called
  YAML *frontmatter*.

- The body of the template contains the prompt. It can also optionally include
  system instructions and input values (using
  [Handlebars](https://handlebarsjs.com/guide/) syntax).

| **Important:** Make sure to review the list of [not-yet-supported features](https://firebase.google.com/docs/ai-logic/server-prompt-templates/best-practices-and-considerations) for the initial release of server prompt templates.

<br />

This page provides detailed descriptions of the template format and syntax,
along with examples, for the following:

- [**Gemini**]()

  - [Hello world](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#gemini-hello-world)

  - [Model configuration](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#gemini-model-config)

  - [System instructions](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#gemini-system-instructions)

  - [Input variables](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#gemini-input-variables)

  - [Control flows (loops \& conditionals)](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#gemini-control-flows)

  - [Input validation and schema](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#gemini-input-validation-and-schema)

  - [Output schema](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#gemini-output-schema)

  - [Multimodal input](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#gemini-multimodal-input)

- [**Imagen**](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#imagen)

  - [Basic](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#imagen-basic)

  - [Advanced](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#imagen-advanced)

<br />

*** ** * ** ***

## **Gemini**

All the examples in this section show templates that use `gemini-2.5-flash`, but
you can use any Gemini model supported by Firebase AI Logic
(except for Gemini Live models).

### Hello world

Here's a minimal example of a server prompt template:

**Configuration (frontmatter)**  

    ---
    model: 'gemini-2.5-flash'
    ---

**Prompt and (as applicable) system instructions**  

    Write a story about a magic backpack.

<br />

### Control generation of responses

You can control the generation of responses in a variety of ways depending on
your use case and the level of control that you need.

#### Model configuration

Set a [model configuration](https://firebase.google.com/docs/ai-logic/model-parameters) to control how the
model generates a response,
like max output tokens, temperature, top-K, and top-P.

**Configuration (frontmatter)**  

    ---
    model: 'gemini-2.5-flash'
    config:
      candidateCount: 1
      temperature: 0.9
      topP: 0.1
      topK: 16
      maxOutputTokens: 200
      stopSequences: ["red"]
    ---

**Prompt and (as applicable) system instructions**  

    Write a story about a magic backpack.

<br />

#### Thinking configuration

Specify a [thinking-related configuration](https://firebase.google.com/docs/ai-logic/thinking) for models
that support thinking.

**Configuration (frontmatter)**  

    ---
    model: 'gemini-2.5-flash'
    config:
      thinkingConfig:
        thinkingBudget: 1024
        includeThoughts: true
    ---

**Prompt and (as applicable) system instructions**  

    Solve x^2 + 4x + 4 = 0

<br />

#### Safety settings

Use [safety settings](https://firebase.google.com/docs/ai-logic/safety-settings) to adjust the likelihood
of getting responses that may be considered harmful.

**Configuration (frontmatter)**

Example with one safety setting:  

    ---
    model: 'gemini-2.5-flash'
    config:
      safetySettings:
        - category: HARM_CATEGORY_HARASSMENT
          threshold: BLOCK_ONLY_HIGH
    ---

Example with multiple safety settings:  

    ---
    model: 'gemini-2.5-flash'
    config:
      safetySettings:
        - category: HARM_CATEGORY_HARASSMENT
          threshold: BLOCK_ONLY_HIGH
        - category: HARM_CATEGORY_HATE_SPEECH
          threshold: BLOCK_MEDIUM_AND_ABOVE
    ---

**Prompt and (as applicable) system instructions**  

    Write a story about a magic backpack.

<br />

#### System instructions

Set [system instructions](https://firebase.google.com/docs/ai-logic/system-instructions) to steer the
behavior of the model. You include them as part of the prompt:

- Specify the system instructions using the
  `{{role "system"}}` syntax.

- Specify the text prompt using the
  `{{role "user"}}` syntax.

**Configuration (frontmatter)**  

    ---
    model: 'gemini-2.5-flash'
    ---

**Prompt and (as applicable) system instructions**  

    {{role "system"}}
    All output must be a clearly structured invoice document.
    Use a tabular or clearly delineated list format for line items.

    {{role "user"}}
    Create an example customer invoice for a customer.

<br />

### Input variables

Some prompts are static, but you often need to include some data from the user
as part of the prompt.

You can include dynamic input variables in the prompt using
[Handlebars](https://handlebarsjs.com/guide/) expressions, which
are contained within `{{ }}` tags in the format
of `{{variableName}}` or
`{{object.propertyName}}` (for example,
`Hello, {{name}} from {{address.city}}`).
| **Important:** Always provide [input validation](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#gemini-input-validation-and-schema) to ensure that the data passed in the request matches your expectations. Note that if you use an input variable in your prompt and you provide input validation schema, then that value is considered required (unless you denote it as optional in the schema).

**Configuration (frontmatter)**  

    ---
    model: 'gemini-2.5-flash'
    ---

**Prompt and (as applicable) system instructions**  

    Create an example customer invoice for a customer named {{customerName}}.

You can provide a [default value](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#gemini-input-validation-and-schema) in the
template, but the value of an input variable is usually provided by the client
as part of the request.

<br />

View client-side request that provides input values

<br />

|---|
| *Click your Gemini API provider to view provider-specific content and code on this page.* Gemini Developer API Vertex AI Gemini API |

### Swift


    // ...

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

    let customerName = "Jane"

    do {
        let response = try await model.generateContent(
            // Specify your template ID
            templateID: "my-first-template-v1-0-0",
            // Provide the values for any input variables required by your template.
            inputs: [
                "customerName": customerName
            ]
        )
        if let text = response.text {
            print("Response Text: \(text)")
        }
    } catch {
        print("An error occurred: \(error)")
    }
    print("\n")

### Kotlin


    // ...

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

    val customerName = "Jane"

    val response = model.generateContent(
        // Specify your template ID
        "my-first-template-v1-0-0",
        // Provide the values for any input variables required by your template.
        mapOf(
            "customerName" to customerName
        )
    )

    val text = response.text
    println(text)

### Java


    // ...

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

    TemplateGenerativeModelFutures model = TemplateGenerativeModelFutures.from(generativeModel);

    String customerName = "Jane";

    Future response = model.generateContent(
        // Specify your template ID
        "my-first-template-v1-0-0",
        // Provide the values for any input variables required by your template.
        mapOf("customerName", customerName)
    );
    addCallback(response,
           new FutureCallback() {
               public void onSuccess(GenerateContentResponse result) {
                 System.out.println(result.getText());
               }
               public void onFailure(Throwable t) {
                 reportError(t);
               }
        }
    executor);

### Web


    // ...

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

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

    const customerName = 'Jane';

    const result = await model.generateContent(
      // Specify your template ID
      'my-first-template-v1-0-0',
      // Provide the values for any input variables required by your template
      {
        customerName: customerName,
      }
    );

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

### Dart


    // ...

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

    var customerName = 'Jane';

    var response = await _model.generateContent(
            // Specify your template ID
            'my-first-template-v1-0-0',
            // Provide the values for any input variables required by your template
            inputs: {
               'customerName': customerName,
            },
          );

    var text = response?.text;
    print(text);

### Unity


    // ...

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

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

    var customerName = "Jane";

    try
    {
       var response = await model.GenerateContentAsync(
          // Specify your template ID
          "my-first-template-v1-0-0",
          // Provide the values for any input variables required by your template
          new Dictionary<string, object> {
             { "customerName", customerName },
          }
       );
       Debug.Log($"Response Text: {response.Text}");
    }
    catch (Exception e) {
      Debug.LogError($"An error occurred: {e.Message}");
    }

<br />

<br />

<br />

### Control flows (loops \& conditionals)

To write more complex prompts, you can use conditional blocks (like `#if` ,
`else`, and `#unless`) and iteration (`#each`).

You can provide additional contextual information as variables with a special
`@` prefix:

- `@first`: true when iterating the first item of an `#each` block.
- `@last`: true when iterating the last item of an `#each` block.
- `@index`: gives the (zero-based) index position of the current element.

See the
[Handlebars documentation](https://handlebarsjs.com/guide/builtin-helpers.html)
for information on all of the built-in logical helpers.

**Configuration (frontmatter)**  

    ---
    model: 'gemini-2.5-flash'
    ---

**Prompt and (as applicable) system instructions**  

    Create an example customer invoice for a customer named {{customerName}}.

    Include entries for each of the following products

    {{#each productNames}}
      {{#if @first}}
      Include line items for the following purchases
      {{/if}}
      - {{this}}
    {{/each}}

    {{#if isVipCustomer}}
    Give the customer a 5% discount.
    {{/if}}

Note that conditionals only accept a variable reference, not any type of
expression, for example:

- The following works: `{{#if isVipCustomer}} ... {{/if}}`
- The following does *not* work: `{{#if customer.type == 'vip'}} ... {{/if}}`

If the variable is a boolean, then the conditional works as you would expect.
If the variable is *not* a boolean then the conditional is effectively an
"is-not-null" check. This can be useful for handling optional inputs, for
example:  

    {{#if customerName}}
    Hello {{customerName}}
    {{else}}
    Hello Guest
    {{/if}}

<br />

### Input validation and schema

If you have data coming from the client, we strongly recommend using input
schema to help protect against prompt injection as well as ensure that the data
passed in the request matches your expectations.

- You can provide default values in case the client doesn't provide a value.

- The schema supports scalar types `string`, `integer`, `number`, `boolean`, and
  `object`. Objects, arrays, and enums are denoted by a parenthetical after the
  field name.

- All properties are considered required unless you denote it as optional with
  `?`. When a property is marked as optional, it's also made nullable to provide
  more leniency for LLMs to return null instead of omitting a field.

| **Note:** If you specify an input schema and the client fails to pass valid inputs with a request, then the request will be rejected with a 400 error.

Here's a **basic example** for providing input schema. You can find a more
advanced schema just below.

**Configuration (frontmatter)**  

    ---
    model: 'gemini-2.5-flash'
    input:
      default:
        isVipCustomer: false
      schema:
        customerName: string, the customers name  # string, number, and boolean types are defined like this
        productNames?(array, list of products to include in the invoice): string  # optional fields are marked with a ?
        isVipCustomer?: boolean, whether or not the customer is a VIP
    ---

**Prompt and (as applicable) system instructions**  

    Create an example customer invoice for a customer named {{customerName}}.

    Include entries for each of the following products

    {{#each productNames}}
      {{#if @first}}
      Include line items for the following purchases
      {{/if}}
      - {{this}}
    {{/each}}

    {{#if isVipCustomer}}
    Give the customer a 5% discount.
    {{/if}}

<br />

View a more **complex example** for providing input schema

<br />

**Configuration (frontmatter)**  

    ---
    model: gemini-2.5-flash
    input:
      schema:
        customer:
          type: object
          description: details about the customer
          required: [lastName, address]
          properties:
            firstName:
              type: string
              minLength: 2
              maxLength: 50
            lastName:
              type: string
              minLength: 2
              maxLength: 50
            address:
              type: object
              description: customer's address
              required: [street, city, country]
              properties:
                street:
                  type: string
                city:
                  type: string
                country:
                  type: string
            isVip:
              type: boolean
              description: whether or not the customer is a VIP
        purchases?:
          type: array
          description: list of things the customer purchased
          items:
            type: object
            required: [itemName, sku, cost, quantity]
            properties:
              itemName:
                type: string
              sku:
                type: string
                minLength: 7
                maxLength: 19
                pattern: "^[0-9]{1,3}-[a-zA-Z]{3,10}-[0-9]{1,4}$"
              category:
                enum: ["ELECTRONICS", "APPAREL", "HOME", "MISC" ]
              cost:
                type: number
                minimum: 0
              quantity:
                type: number
                minimum: 1
                maximum: 200
    ---

**Prompt and (as applicable) system instructions**  

    Create an example customer invoice for a customer.

    The customer's address is

    {{customer.firstName}} {{customer.lastName}}
    {{customer.address.street}}
    {{customer.address.city}}
    {{customer.address.country}}

    {{#each purchases}}
      {{#if @first}}
      Include line items for the following purchaes
      {{/if}}
      - {{quantity}} x {{itemName}} ({{sku}}) @ ${{cost}}, category {{category}}
    {{/each}}

    {{#if customer.isVip}}
    Give the customer a 5% discount.
    {{/if}}

<br />

<br />

<br />

### Output schema

If you want the model to generate
[structured JSON output](https://firebase.google.com/docs/ai-logic/generate-structured-output),
then you can specify an output schema. By specifying `format: json`, you're
constraining the model to always return a JSON response that follows the
specified schema.

- The schema supports scalar types `string`, `integer`, `number`, `boolean`, and
  `object`. Objects, arrays, and enums are denoted by a parenthetical after the
  field name.

- All properties are considered required unless you denote it as optional with
  `?`. When a property is marked as optional, it's also made nullable to provide
  more leniency for LLMs to return null instead of omitting a field.

| **Note:** Server prompt templates do ***not*** yet support [constraining the output to a list of enums](https://firebase.google.com/docs/ai-logic/generate-structured-output#generate-enum-basic).

Here's a **basic example** for generating structured JSON output. You can
find a more advanced schema just below.

**Configuration (frontmatter)**  

    ---
    model: gemini-2.5-flash
    output:
      format: json
      schema:
        invoiceId: string
        invoiceFile(object, an invoice file):
          url?: string
          contents: string
          mimeType: string
    ---

**Prompt and (as applicable) system instructions**  

    Create an example customer invoice.

<br />

View a more **complex example** for generating structured JSON output

<br />

**Configuration (frontmatter)**  

    ---
    model: gemini-2.5-flash
    output:
      format: json
      schema:
        title: string  # string, number, and boolean types are defined like this
        subtitle?: string  # optional fields are marked with a ?
        draft?: boolean, true when in draft state
        status?(enum, approval status): [PENDING, APPROVED]
        date: string, the date of publication for example '2024-04-09' # descriptions follow a comma
        tags(array, relevant tags for article): string  # arrays are denoted via parentheses
        authors(array):
          name: string
          email?: string
        metadata?(object): # objects are also denoted via parentheses
          updatedAt?: string, ISO timestamp of last update
          approvedBy?: integer, id of approver
        extra?: any, arbitrary extra data
        (*): string, wildcard field
    ---

**Prompt and (as applicable) system instructions**  

    Store all the specified information about the provided article.

<br />

<br />

<br />

### Multimodal input

Multimodal prompts sent to a Gemini model can include multiple types of input,
including [files](https://firebase.google.com/docs/ai-logic/input-file-requirements)
(like text along with images, PDFs, plain-text files, audio, and video).

- Provide a file using its URL with the `{{media url}}`
  syntax.

- Provide an inline file with the
  `{{media type="mime_type" data="contents"}}`
  syntax.

Here's a **basic example** for providing multimodal input. You can find a more
complex example just below.

**Configuration (frontmatter)**  

    ---
    model: 'gemini-2.5-flash'
    ---

**Prompt and (as applicable) system instructions**  

    Describe this image

    {{media type="mimeType" data="imageData"}}

<br />

View how to provide base64-encoded data to test your template in the console

<br />

If your template has input that's base64-encoded data, here's how you can
include it in the testing experience of the Firebase console:  

      {
        "mimeType": "image/png",
        "imageData": " "
      }

<br />

<br />

<br />

View a more **complex example** for providing multimodal input

<br />

**Configuration (frontmatter)**  

    ---
    model: gemini-2.5-flash
    input:
      schema:
        image_urls?(array, urls of external images): string
        inline_images?(array, inline image data):
          type: object
          properties:
            mime_type: string
            contents: string  # inline data must be base64-encoded
    ---

**Prompt and (as applicable) system instructions**  

    {{role "system"}}
    Use the following image as the basis for comparisons
    {{media url="http://example.com/reference_img.bmp"}}

    {{role "user"}}
    What do the following images have in common?

    {{#each image_urls}}
      {{media url="this"}}
    {{/each}}

    {{#each inline_images}}
      {{media type="mime_type" data="contents"}}
    {{/each}}

<br />

<br />

<br />

*** ** * ** ***

## **Imagen** (image generation)

With the initial release, server prompt templates support
[generating images using Imagen models and a text-only prompt](https://firebase.google.com/docs/ai-logic/generate-images-imagen).
Check back soon for more support, including
[editing images with Imagen](https://firebase.google.com/docs/ai-logic/edit-images-imagen-overview)
(when using the Vertex AI Gemini API).

### Basic

This example shows a basic template for generating images with
Imagen, with [input variables](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#gemini-input-variables) and
[input validation](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#gemini-input-validation-and-schema) similar to
Gemini.

**Configuration (frontmatter)**  

    ---
    model: 'imagen-4.0-generate-001'
    input:
      schema:
        prompt: 'string'
    ---

**Prompt and (as applicable) system instructions**  

    Create an image containing {{prompt}}

### Advanced

This example shows how to
add [model configuration](https://firebase.google.com/docs/ai-logic/model-parameters#imagen),
specify [safety settings](https://firebase.google.com/docs/ai-logic/safety-settings#imagen),
and use more advanced features in the prompt, like
[input variables](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#gemini-input-variables),
[input validation](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#gemini-input-validation-and-schema), and
[control flows](https://firebase.google.com/docs/ai-logic/server-prompt-templates/syntax-and-examples#gemini-control-flows)
similar to Gemini.

**Configuration (frontmatter)**  

    ---
    model: 'imagen-4.0-fast-generate-001'
    config:
      sampleCount: 1
      aspectRatio: "16:9"
      personGeneration: dont_allow
      includeRaiReason: true
      safetySetting: block_medium_and_above
    input:
      schema:
        style(enum, The style of image): [photo, sketch, painting]
        subject: string, The object or animal or scenery to generate.
        context?: string, Optional background or context description.
      default:
        style: photo
    ---

**Prompt and (as applicable) system instructions**  

    A {{style}} of {{subject}}{{#if context}}{{context}}{{/if}}.