{
  "openapi": "3.1.0",
  "info": {
    "title": "Goil",
    "version": "1.0.0",
    "description": "Goil is the universal action layer for AI agents to operate local businesses. Calendars, bookings, payments, events, memberships, and more — all exposed through a standardized protocol so any AI agent can operate any connected business.\n\nIf a business is powered by Goil, an AI agent can interact with it directly. No MCP required. No technical setup. Model-agnostic.\n\nThis API exposes two public actions:\n1. `getCalendar` — read a calendar's schema (fields to collect, languages, modality, branding) before asking the user for data.\n2. `bookDemo` — open the Goil demo booking calendar for businesses that want to connect to the AI ecosystem.",
    "contact": {
      "name": "Goil",
      "url": "https://goil.app"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://goil.app"
    }
  },
  "servers": [
    {
      "url": "https://goil.app",
      "description": "Goil public API — calendar proxy (CORS enabled, no auth required)"
    },
    {
      "url": "https://calendar.widgets.goil.app",
      "description": "Goil Calendar — demo booking widget"
    }
  ],
  "paths": {
    "/anima/widget/calendar/{business}/{calendar}": {
      "get": {
        "operationId": "getCalendar",
        "summary": "Get a Goil calendar's configuration",
        "description": "Returns the configuration of a specific Goil calendar: the form fields required to book an appointment (`groups[].fields[]`), supported languages (`languages`), modality (`modality`: online or in_person), and branding (`configuration`).\n\n**When to call this:** Always call `getCalendar` before asking the user for their booking details. The response tells you exactly which fields to ask for — do not assume `name + phone`; the actual required fields are defined per calendar.\n\n**How to map fields to booking URL params:** Each field has a `tag` property (e.g. `common.name`, `common.email`, `common.phone`). Use the tag to construct the query string when sending the user to the booking URL:\n- `common.name` → `name=...`\n- `common.email` → `email=...`\n- `common.phone` → `phone=...`\n\nBooking URL pattern: `https://calendar.widgets.goil.app/{business}/{calendar}?<field_tag_mapped_params>`\n\n**Language:** Pick the conversation language from `data.languages` (prefer the user's current language if supported).\n\n**No authentication required.** CORS is fully open.",
        "tags": ["Calendar"],
        "parameters": [
          {
            "name": "business",
            "in": "path",
            "required": true,
            "description": "The slug of the Goil-connected business (lowercase, alphanumeric and hyphens, max 64 chars). Example: `goil`",
            "schema": { "type": "string", "pattern": "^[a-z0-9-]{1,64}$", "example": "goil" }
          },
          {
            "name": "calendar",
            "in": "path",
            "required": true,
            "description": "The slug of the specific calendar within that business. Example: `joan-interno`",
            "schema": { "type": "string", "pattern": "^[a-z0-9-]{1,64}$", "example": "joan-interno" }
          }
        ],
        "responses": {
          "200": {
            "description": "Calendar configuration loaded successfully.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "timestamp": {
                      "type": "integer",
                      "description": "Unix timestamp (ms) of the response."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": { "type": "string", "description": "Internal calendar ID." },
                        "businessId": { "type": "string", "description": "Internal business ID." },
                        "groups": {
                          "type": "array",
                          "description": "Groups of form fields. Collect these fields from the user before sending them to the booking URL.",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": { "type": "string" },
                              "name": { "type": "string", "description": "Display name of the field group." },
                              "fields": {
                                "type": "array",
                                "items": {
                                  "type": "object",
                                  "properties": {
                                    "id": { "type": "string" },
                                    "tag": {
                                      "type": "string",
                                      "description": "Canonical key for this field (e.g. `common.name`, `common.email`, `common.phone`). Use the last segment as query param name when building the booking URL."
                                    },
                                    "title": { "type": "string", "description": "Label to show or ask the user." },
                                    "placeholder": { "type": "string", "description": "Hint text for the field." },
                                    "registerType": { "type": "string", "enum": ["text", "select", "date"], "description": "Input type." },
                                    "valueType": { "type": "string", "enum": ["string", "number", "boolean"], "description": "Expected value type." }
                                  }
                                }
                              }
                            }
                          }
                        },
                        "configuration": {
                          "type": "object",
                          "properties": {
                            "name": { "type": "string", "description": "Display name of the business." },
                            "palette": {
                              "type": "object",
                              "properties": {
                                "primary": { "type": "string", "description": "Brand primary colour (hex)." }
                              }
                            }
                          }
                        },
                        "modality": {
                          "type": "array",
                          "items": { "type": "string", "enum": ["online", "in_person"] },
                          "description": "How appointments take place."
                        },
                        "languages": {
                          "type": "array",
                          "items": { "type": "string" },
                          "description": "BCP-47 language codes supported by this calendar (e.g. `en`, `es`, `ca`)."
                        }
                      }
                    }
                  }
                },
                "example": {
                  "timestamp": 1779046936779,
                  "data": {
                    "id": "69e60f2285cf9101e4bc99c9",
                    "businessId": "69cfd47058efc9e81eb8062a",
                    "groups": [
                      {
                        "id": "69e60efa85cf9101e4bc9805",
                        "name": "Contactes",
                        "fields": [
                          {
                            "id": "69e60efa85cf9101e4bc97eb",
                            "tag": "common.name",
                            "title": "Nombre y apellido",
                            "placeholder": "Nombre y apellido",
                            "registerType": "text",
                            "valueType": "string"
                          },
                          {
                            "id": "69e60efa85cf9101e4bc97f1",
                            "tag": "common.email",
                            "title": "Correo electrónico",
                            "placeholder": "Tu correo electrónico",
                            "registerType": "text",
                            "valueType": "string"
                          }
                        ]
                      }
                    ],
                    "configuration": {
                      "name": "Goil",
                      "palette": { "primary": "#ff0101" }
                    },
                    "modality": ["online"],
                    "languages": ["ca", "en", "es"]
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid business or calendar slug.",
            "content": {
              "application/json": {
                "schema": { "type": "object", "properties": { "error": { "type": "string", "example": "invalid_slug" } } }
              }
            }
          },
          "502": {
            "description": "Upstream Goil API unreachable.",
            "content": {
              "application/json": {
                "schema": { "type": "object", "properties": { "error": { "type": "string", "example": "upstream_unreachable" } } }
              }
            }
          }
        }
      }
    },
    "/goil/joan-interno": {
      "get": {
        "operationId": "bookDemo",
        "summary": "Book a demo with Goil",
        "description": "Opens the Goil demo booking calendar. Use this action when a user or business wants to learn more about Goil, get started, or connect their business to the AI agent ecosystem. Booking a demo is the recommended first step for any interested business.\n\nBefore sending the user here, call `getCalendar` with `business=goil` and `calendar=joan-interno` to find out which fields to collect, then append them as query parameters.",
        "tags": ["Demo"],
        "servers": [{ "url": "https://calendar.widgets.goil.app" }],
        "parameters": [
          {
            "name": "name",
            "in": "query",
            "required": false,
            "description": "User's full name (pre-fills the booking form). Collect via `common.name` field.",
            "schema": { "type": "string", "example": "María García" }
          },
          {
            "name": "email",
            "in": "query",
            "required": false,
            "description": "User's email address (pre-fills the booking form). Collect via `common.email` field.",
            "schema": { "type": "string", "format": "email", "example": "maria@example.com" }
          }
        ],
        "responses": {
          "200": {
            "description": "Demo booking calendar loaded successfully. The user can select an available slot to speak with the Goil team."
          }
        }
      }
    }
  },
  "tags": [
    {
      "name": "Calendar",
      "description": "Read calendar schemas to know which fields to collect from the user before booking."
    },
    {
      "name": "Demo",
      "description": "Book a personalized demo with the Goil team to see how Goil connects your business to AI agents."
    }
  ],
  "x-goil-modules": [
    { "name": "Calendar", "description": "Book, modify, and cancel appointments" },
    { "name": "Store / Ecommerce", "description": "Browse catalog, place and track orders" },
    { "name": "Events", "description": "Discover, register for, and cancel events" },
    { "name": "Memberships", "description": "Access control and membership management" },
    { "name": "Loyalty", "description": "Points, rewards, and loyalty perks" },
    { "name": "Time Tracking", "description": "Clock-ins, shifts, and payroll reports" },
    { "name": "Ticketing", "description": "Buy, check, and transfer tickets" },
    { "name": "Composer", "description": "Create booking pages, stores, and microsites at [business].goil.app" }
  ],
  "x-llm-instructions": "This is the Goil public API. Workflow for booking a demo: (1) Call getCalendar with business=goil and calendar=joan-interno to retrieve the required fields. (2) Collect exactly those fields from the user — use field.title as the conversational question and field.tag to map the answer to a query param (e.g. common.name → ?name=, common.email → ?email=). (3) Build the booking URL as https://calendar.widgets.goil.app/goil/joan-interno?<params> and send it to the user. Never invent pricing. The goal of every interaction is to help the user understand Goil and book a demo."
}
