VitrinaAPI

Macros

Saved replies with automated side-effects an agent applies in one click.

Beta
This may change at any time, with a changelog entry and a notice to recent callers — see versioning.

Download the full API pública projection: openapi.json.

Automate replies and assignment explains this resource in prose, with runnable examples.

MethodPathWhat it does
GET/macrosList macros
POST/macrosCreate a macro
DELETE/macros/{id}Delete a macro
GET/macros/{id}Fetch one macro
PUT/macros/{id}Update a macro
GET/macros/{id}/prepareResolve a macro for the composer

GET /macros

List macros

Every macro in the workspace with its content, actions, params and usage counters. Unfiltered — active, visibility and available_for come back on each row for the caller to filter on, and inactive macros are included.

curl https://api.vitrinadev.com/api/v1/macros \
  -H "Authorization: Bearer $VITRINA_KEY"

Example response (200)

{
  "data": [
    {
      "id": "d3d3d3d3-0000-4000-8000-000000000001",
      "tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
      "name": "Cierre agradecido",
      "description": "Agradece, etiqueta como resuelto y cambia el estado del ticket.",
      "category": "cierre",
      "content": "Gracias por escribirnos, [[nombre]]. Cualquier otra duda, aquí estamos.",
      "shortcut": "cierre",
      "actions": [
        {
          "id": "a1",
          "type": "add_tag",
          "value": [
            "resuelto"
          ]
        },
        {
          "id": "a2",
          "type": "change_status",
          "value": "resolved"
        }
      ],
      "params": [
        {
          "key": "nombre",
          "label": "Nombre del cliente",
          "input_type": "text"
        }
      ],
      "icon": "play",
      "visibility": "public",
      "available_for": "everyone",
      "run_when": [
        "manual"
      ],
      "active": true,
      "usage_count": 42,
      "last_used_at": "2026-09-15T18:20:00.000Z",
      "created_at": "2026-01-10T13:00:00.000Z",
      "updated_at": "2026-09-10T13:00:00.000Z"
    }
  ],
  "meta": {
    "total": 1
  }
}

Answers: 200 · 400 · 401 · 403 · 404 · 409 · 429

POST /macros

Create a macro

Only name is required. An action-only macro is valid — one that just changes status and adds a label, with no content, is a normal thing to build.

actions is an untyped list: the step objects are stored as given and validated only when the macro RUNS. A typo in a step type creates cleanly and then reports unknown action type on every execution, so run a macro once after authoring it.

Each entry in params declares one [[manual]] placeholder, and its key must match the placeholder text in content for the composer to pair them up. Defaults: icon: "play", visibility: "public", available_for: "everyone", run_when: ["manual"], active: true. Answers 201.

Body

FieldTypeRequiredConstraints
namestringyesmín. 1, máx. 200
descriptionstring | null—máx. 2000
categorystring | null—máx. 100
contentstring—máx. 8000, por defecto ""
shortcutstring | null—máx. 50
actionsany[]—
paramsobject[]—
iconstring—máx. 60
visibilitypublic \private—
available_forstring—máx. 120
run_whenstring[]—
activeboolean—
curl -X POST https://api.vitrinadev.com/api/v1/macros \
  -H "Authorization: Bearer $VITRINA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Cierre agradecido",
    "content": "Gracias por escribirnos, [[nombre]]. Cualquier otra duda, aquí estamos.",
    "actions": [
      {
        "id": "a1",
        "type": "add_tag",
        "value": [
          "resuelto"
        ]
      }
    ],
    "params": [
      {
        "key": "nombre",
        "label": "Nombre del cliente",
        "input_type": "text"
      }
    ]
  }'

Example response (201)

{
  "data": {
    "id": "d3d3d3d3-0000-4000-8000-000000000001",
    "tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
    "name": "Cierre agradecido",
    "description": "Agradece, etiqueta como resuelto y cambia el estado del ticket.",
    "category": "cierre",
    "content": "Gracias por escribirnos, [[nombre]]. Cualquier otra duda, aquí estamos.",
    "shortcut": "cierre",
    "actions": [
      {
        "id": "a1",
        "type": "add_tag",
        "value": [
          "resuelto"
        ]
      },
      {
        "id": "a2",
        "type": "change_status",
        "value": "resolved"
      }
    ],
    "params": [
      {
        "key": "nombre",
        "label": "Nombre del cliente",
        "input_type": "text"
      }
    ],
    "icon": "play",
    "visibility": "public",
    "available_for": "everyone",
    "run_when": [
      "manual"
    ],
    "active": true,
    "usage_count": 42,
    "last_used_at": "2026-09-15T18:20:00.000Z",
    "created_at": "2026-01-10T13:00:00.000Z",
    "updated_at": "2026-09-10T13:00:00.000Z"
  }
}

Answers: 201 · 400 · 401 · 403 · 404 · 409 · 429

DELETE /macros/{id}

Delete a macro

Removes the macro. Everything it already did — messages sent, labels applied, status changes — stays; a macro is an action, not a relationship. Set active: false to retire one without losing its usage history.

ParameterInTypeRequiredConstraints
idpathuuidyes
curl -X DELETE https://api.vitrinadev.com/api/v1/macros/<id> \
  -H "Authorization: Bearer $VITRINA_KEY"

Answers: 204 · 400 · 401 · 403 · 404 · 409 · 429

GET /macros/{id}

Fetch one macro

The macro as stored, including usage_count and last_used_at.

ParameterInTypeRequiredConstraints
idpathuuidyes
curl https://api.vitrinadev.com/api/v1/macros/<id> \
  -H "Authorization: Bearer $VITRINA_KEY"

Example response (200)

{
  "data": {
    "id": "d3d3d3d3-0000-4000-8000-000000000001",
    "tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
    "name": "Cierre agradecido",
    "description": "Agradece, etiqueta como resuelto y cambia el estado del ticket.",
    "category": "cierre",
    "content": "Gracias por escribirnos, [[nombre]]. Cualquier otra duda, aquí estamos.",
    "shortcut": "cierre",
    "actions": [
      {
        "id": "a1",
        "type": "add_tag",
        "value": [
          "resuelto"
        ]
      },
      {
        "id": "a2",
        "type": "change_status",
        "value": "resolved"
      }
    ],
    "params": [
      {
        "key": "nombre",
        "label": "Nombre del cliente",
        "input_type": "text"
      }
    ],
    "icon": "play",
    "visibility": "public",
    "available_for": "everyone",
    "run_when": [
      "manual"
    ],
    "active": true,
    "usage_count": 42,
    "last_used_at": "2026-09-15T18:20:00.000Z",
    "created_at": "2026-01-10T13:00:00.000Z",
    "updated_at": "2026-09-10T13:00:00.000Z"
  }
}

Answers: 200 · 400 · 401 · 403 · 404 · 409 · 429

PUT /macros/{id}

Update a macro

A PUT that behaves as a PATCH; at least one field is required. actions and params are each replaced wholesale when sent, so a step list must be sent complete.

Editing takes effect immediately for anyone about to run it. The usage counters are not editable here.

ParameterInTypeRequiredConstraints
idpathuuidyes

Body

FieldTypeRequiredConstraints
namestring—mín. 1, máx. 200
descriptionstring | null—máx. 2000
categorystring | null—máx. 100
contentstring—máx. 8000, por defecto ""
shortcutstring | null—máx. 50
actionsany[]—
paramsobject[]—
iconstring—máx. 60
visibilitypublic \private—
available_forstring—máx. 120
run_whenstring[]—
activeboolean—
curl -X PUT https://api.vitrinadev.com/api/v1/macros/<id> \
  -H "Authorization: Bearer $VITRINA_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "active": false
  }'

Example response (200)

{
  "data": {
    "id": "d3d3d3d3-0000-4000-8000-000000000001",
    "tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
    "name": "Cierre agradecido",
    "description": "Agradece, etiqueta como resuelto y cambia el estado del ticket.",
    "category": "cierre",
    "content": "Gracias por escribirnos, [[nombre]]. Cualquier otra duda, aquí estamos.",
    "shortcut": "cierre",
    "actions": [
      {
        "id": "a1",
        "type": "add_tag",
        "value": [
          "resuelto"
        ]
      },
      {
        "id": "a2",
        "type": "change_status",
        "value": "resolved"
      }
    ],
    "params": [
      {
        "key": "nombre",
        "label": "Nombre del cliente",
        "input_type": "text"
      }
    ],
    "icon": "play",
    "visibility": "public",
    "available_for": "everyone",
    "run_when": [
      "manual"
    ],
    "active": false,
    "usage_count": 42,
    "last_used_at": "2026-09-15T18:20:00.000Z",
    "created_at": "2026-01-10T13:00:00.000Z",
    "updated_at": "2026-09-10T13:00:00.000Z"
  }
}

Answers: 200 · 400 · 401 · 403 · 404 · 409 · 429

GET /macros/{id}/prepare

Resolve a macro for the composer

Renders the macro against a live conversation WITHOUT sending or changing anything. Answers \{ macro, segments, manual_params, effects \}.

segments is the reply broken into resolved text and still-unfilled placeholders, so a composer can render the draft with gaps in place. manual_params is the [[manual]] params the agent must fill, with their input types and options. effects summarises the non-message actions so the agent can see what else pressing send will do.

The reply text is the macro’s FIRST send_message action, falling back to content. A macro with several send_message steps previews only the first here, though running it sends them all.

Read-only and side-effect free — unlike /apply, it does not touch usage_count.

ParameterInTypeRequiredConstraints
idpathuuidyes
conversation_idquerystringyesmín. 1
curl https://api.vitrinadev.com/api/v1/macros/<id>/prepare \
  -H "Authorization: Bearer $VITRINA_KEY"

Example response (200)

{
  "data": {
    "macro": {
      "id": "d3d3d3d3-0000-4000-8000-000000000001",
      "tenant_id": "a1a1a1a1-0000-4000-8000-000000000001",
      "name": "Cierre agradecido",
      "description": "Agradece, etiqueta como resuelto y cambia el estado del ticket.",
      "category": "cierre",
      "content": "Gracias por escribirnos, [[nombre]]. Cualquier otra duda, aquí estamos.",
      "shortcut": "cierre",
      "actions": [
        {
          "id": "a1",
          "type": "add_tag",
          "value": [
            "resuelto"
          ]
        },
        {
          "id": "a2",
          "type": "change_status",
          "value": "resolved"
        }
      ],
      "params": [
        {
          "key": "nombre",
          "label": "Nombre del cliente",
          "input_type": "text"
        }
      ],
      "icon": "play",
      "visibility": "public",
      "available_for": "everyone",
      "run_when": [
        "manual"
      ],
      "active": true,
      "usage_count": 42,
      "last_used_at": "2026-09-15T18:20:00.000Z",
      "created_at": "2026-01-10T13:00:00.000Z",
      "updated_at": "2026-09-10T13:00:00.000Z"
    },
    "segments": [
      {
        "text": "Gracias por escribirnos, ",
        "resolved": true
      },
      {
        "text": "[[nombre]]",
        "resolved": false
      }
    ],
    "manual_params": [
      {
        "key": "nombre",
        "label": "Nombre del cliente",
        "input_type": "text"
      }
    ],
    "effects": [
      "Etiqueta: resuelto",
      "Cambia el estado a resolved"
    ]
  }
}

Answers: 200 · 400 · 401 · 403 · 404 · 409 · 429

On this page