> ## Documentation Index
> Fetch the complete documentation index at: https://fliqr.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Dynamic content from your API

> Return messages and actions from your server so Fliqr AI can deliver channel-ready content inside a Flow External Request.

Dynamic content lets **your API** generate the messages a contact sees. Instead of hard-coding every card on the canvas, an [External Request](/docs/core-concepts/flows/external-requests) returns a JSON payload that Fliqr AI converts and delivers on WhatsApp, Messenger, Instagram, and other channels.

<Note>
  You need to control the API response shape. If you only consume a third-party API, map fields with Response Mapping and show them with `{{custom_fields}}` instead.
</Note>

## Response envelope

```json theme={null}
{
  "messages": [],
  "actions": []
}
```

* **`messages`** — content sent to the contact
* **`actions`** — side effects (tags, fields, send Flow, Inbox transfer)

Fliqr AI sends an `X-USER-ID` header on every External Request so your server can identify the contact.

## Response mapping helpers

When you map a normal JSON API (not dynamic content), these special paths are available:

| Path                                     | Saves                               |
| ---------------------------------------- | ----------------------------------- |
| `http_status_code`                       | HTTP status code                    |
| `http_response_body`                     | Full response body                  |
| `http_download_mp3` (or other extension) | Downloaded file for that media type |

Use `http_status_code` with a [Condition](/docs/core-concepts/flows/conditions) to branch on success vs client/server errors.

## Message examples

### Text

```json theme={null}
{
  "messages": [
    {
      "message": {
        "text": "Hello world",
        "quick_replies": []
      }
    }
  ]
}
```

### Multiple messages

```json theme={null}
{
  "messages": [
    { "message": { "text": "Hello world" } },
    { "message": { "text": "This is the second message", "quick_replies": [] } }
  ]
}
```

### Text with buttons

Up to **3** buttons. Button titles up to **20** characters. Use a Flow or step ID as `payload` to continue the conversation.

```json theme={null}
{
  "messages": [
    {
      "message": {
        "attachment": {
          "type": "template",
          "payload": {
            "template_type": "button",
            "text": "Hello world",
            "buttons": [
              {
                "title": "Open Website",
                "type": "web_url",
                "url": "https://example.com"
              },
              {
                "title": "Send Flow",
                "type": "postback",
                "payload": "FLOW_OR_STEP_ID"
              },
              {
                "title": "Call Number",
                "type": "phone_number",
                "payload": "+15551234567"
              }
            ]
          }
        },
        "quick_replies": []
      }
    }
  ]
}
```

### Quick replies

Attach up to **11** quick replies to text, media, or cards. Payload rules match buttons.

```json theme={null}
{
  "messages": [
    {
      "message": {
        "text": "Hello world",
        "quick_replies": [
          {
            "content_type": "text",
            "title": "Quick Reply 1",
            "payload": "FLOW_OR_STEP_ID"
          }
        ]
      }
    }
  ]
}
```

### Image, video, audio, or file

Change `type` to `image`, `video`, `audio`, or `file`.

```json theme={null}
{
  "messages": [
    {
      "message": {
        "attachment": {
          "type": "image",
          "payload": { "url": "https://example.com/asset.jpg" }
        },
        "quick_replies": []
      }
    }
  ]
}
```

### Card or gallery

Card title/subtitle up to **80** characters. Up to **3** buttons per card. Galleries up to **10** cards. `image_aspect_ratio`: `horizontal` or `square`.

```json theme={null}
{
  "messages": [
    {
      "message": {
        "attachment": {
          "type": "template",
          "payload": {
            "template_type": "generic",
            "image_aspect_ratio": "horizontal",
            "elements": [
              {
                "title": "Card Title 1",
                "subtitle": "Card Subtitle 1",
                "image_url": "https://example.com/1.jpg",
                "buttons": []
              },
              {
                "title": "Card Title 2",
                "subtitle": "Card Subtitle 2",
                "image_url": "https://example.com/2.jpg",
                "buttons": []
              }
            ]
          }
        },
        "quick_replies": []
      }
    }
  ]
}
```

## WhatsApp-only payloads

For lists, catalogs, contacts, or other WhatsApp interactive types, return the [WhatsApp Cloud API](https://developers.facebook.com/docs/whatsapp/cloud-api/guides/send-messages) message object inside `messages`. Fliqr AI sets the recipient for you — keep `"to": null`.

```json theme={null}
{
  "messages": [
    {
      "messaging_product": "whatsapp",
      "recipient_type": "individual",
      "to": null,
      "type": "interactive",
      "interactive": {
        "type": "button",
        "body": { "text": "ANY TEXT" },
        "action": {
          "buttons": [
            {
              "type": "reply",
              "reply": { "id": "FLOW_OR_STEP_ID", "title": "BUTTON_TITLE_1" }
            }
          ]
        }
      }
    }
  ]
}
```

## Actions in the response

Run side effects alongside (or instead of) messages.

| Action                                          | Purpose                                                                                                               |
| ----------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
| `add_tag` / `remove_tag`                        | Manage tags (`tag_name`)                                                                                              |
| `set_field_value` / `unset_field_value`         | Set or clear a custom field (`field_name`, `value`) — also works for system fields like `phone`, `email`, `full_name` |
| `send_flow`                                     | Start a Flow by numeric `flow_id`                                                                                     |
| `transfer_conversation_to`                      | `"human"` or `"bot"`                                                                                                  |
| `assign_conversation` / `unassign_conversation` | Inbox assignment (`admin_id`)                                                                                         |

Example — set a field and send a Flow:

```json theme={null}
{
  "messages": [],
  "actions": [
    {
      "action": "set_field_value",
      "field_name": "order_status",
      "value": "paid"
    },
    {
      "action": "send_flow",
      "flow_id": "123456"
    }
  ]
}
```

Find a Flow ID from **Flows → ⋮ → Get Link** (numeric ID in the URL).

### Actions as button payloads

Payloads are strings. JSON-encode the actions object:

```json theme={null}
{
  "title": "Click Here",
  "type": "postback",
  "payload": "{\"actions\":[{\"action\":\"send_flow\",\"flow_id\":\"FLOW_OR_STEP_ID\"}]}"
}
```

## Limits

* Default External Request rate: **100 requests / 60 seconds** per bot account
* Channel button, card, and media limits still apply after conversion

## Next

<CardGroup cols={2}>
  <Card title="External requests" icon="plug" href="/docs/core-concepts/flows/external-requests">
    Add the block, headers, and success/failure paths.
  </Card>

  <Card title="Extract JSON" icon="file-code" href="/docs/core-concepts/flows/extract-json">
    Pull individual fields from JSON with JSONPath.
  </Card>
</CardGroup>
