{
  "version": "2",
  "generatedAt": "2026-11-03T22:49:39.280Z",
  "listing": {
    "slug": "alextselegidis--easyappointments",
    "name": "Easy!Appointments",
    "tagline": "Self-hosted appointment booking for providers and services with a Builder-published REST API and OpenAPI file.",
    "shortTagline": "Appointment booking",
    "description": "Easy!Appointments is a PHP booking system: services, providers with working plans and booking rules, customers, a public booking page, Google Calendar sync and email notifications. The Builder documents a REST API (docs/rest-api.md, openapi.yml) covering appointments, availabilities, customers, services, providers, secretaries, admins and settings. Configuration is a single config.php; premium services and white-label licenses are sold separately.",
    "capabilities": [
      "adaptable",
      "operable"
    ],
    "vertical": "scheduling-staffing",
    "alternativeTo": [
      "Calendly",
      "Acuity Scheduling",
      "SimplyBook.me"
    ],
    "shape": "business-app",
    "formFactor": "web-app",
    "executionModel": "deterministic",
    "provenance": "human-written",
    "codeStack": {
      "languages": [
        "PHP",
        "JavaScript"
      ],
      "frameworks": [
        "CodeIgniter"
      ],
      "packageManager": "composer",
      "database": [
        "MySQL"
      ],
      "hostingTarget": [
        "apache",
        "nginx",
        "docker"
      ]
    },
    "modelStack": null,
    "repos": [
      {
        "url": "https://github.com/alextselegidis/easyappointments",
        "owner": "alextselegidis",
        "name": "easyappointments",
        "license": "GPL-3.0",
        "stars": 4351,
        "lastCommit": "2026-09-02"
      }
    ],
    "interface": {
      "kind": "api",
      "url": "https://github.com/alextselegidis/easyappointments/blob/master/docs/rest-api.md",
      "official": true,
      "hosted": "both"
    },
    "operability": "official",
    "recommendedWrapper": null,
    "reach": [
      {
        "job": "Book, move and cancel appointments",
        "reachable": true,
        "evidence": "docs/rest-api.md: GET/POST/PUT/DELETE /api/v1/appointments"
      },
      {
        "job": "Find open slots for a provider and service",
        "reachable": true,
        "evidence": "GET /api/v1/availabilities?providerId&serviceId&date"
      },
      {
        "job": "Manage customers",
        "reachable": true,
        "evidence": "Customers resource in docs/rest-api.md"
      },
      {
        "job": "Manage services and categories",
        "reachable": true,
        "evidence": "Services and Service Categories resources"
      },
      {
        "job": "Manage providers, secretaries and admins",
        "reachable": true,
        "evidence": "Providers, Secretaries and Admins resources"
      },
      {
        "job": "Block time off (unavailabilities)",
        "reachable": true,
        "evidence": "Unavailabilities resource"
      },
      {
        "job": "Read and change system settings",
        "reachable": true,
        "evidence": "Settings resource"
      },
      {
        "job": "Sync a provider with Google Calendar",
        "reachable": false,
        "evidence": "OAuth consent is done by the provider in the backend UI; no sync endpoint in the API"
      },
      {
        "job": "Send booking notification emails",
        "reachable": null,
        "evidence": "emails are sent by the app on booking events; not stated whether API-created appointments trigger them"
      }
    ],
    "editions": [
      {
        "name": "Free",
        "price": null,
        "open": true,
        "distributions": [
          {
            "kind": "source",
            "url": "https://github.com/alextselegidis/easyappointments"
          },
          {
            "kind": "container",
            "url": "https://github.com/alextselegidis/easyappointments/blob/master/docs/docker.md",
            "command": "docker compose up"
          }
        ]
      },
      {
        "name": "Premium services and white-label licenses",
        "price": null,
        "open": false,
        "distributions": [
          {
            "kind": "hosted",
            "url": "https://easyappointments.org/premium"
          }
        ]
      }
    ],
    "skills": {
      "kind": "none",
      "paths": [],
      "install": null,
      "note": "No SKILL.md, Claude Code plugin, or skills install target in the repo."
    },
    "customization": {
      "summary": "Rename config-sample.php to config.php and set BASE_URL, LANGUAGE, DB_HOST, DB_NAME, DB_USERNAME and DB_PASSWORD; enable GOOGLE_SYNC_FEATURE with GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET if providers sync calendars. The Docker image takes the same names as environment variables (docs/docker.md). Services, providers, working plans, booking rules and email settings are set in the backend after the setup wizard.",
      "envVars": [
        "BASE_URL",
        "LANGUAGE",
        "DEBUG_MODE",
        "DB_HOST",
        "DB_NAME",
        "DB_USERNAME",
        "DB_PASSWORD",
        "GOOGLE_SYNC_FEATURE",
        "GOOGLE_CLIENT_ID",
        "GOOGLE_CLIENT_SECRET"
      ],
      "configFiles": [
        "config-sample.php",
        "config.php",
        "docker-compose.yml"
      ],
      "promptFiles": [],
      "effort": "config-only",
      "editCount": 13
    },
    "useWhen": [
      "my clinic or salon needs a booking page per provider with working hours and services, on ordinary PHP hosting",
      "I want my agent to check availability and book clients into staff calendars through a plain REST API"
    ],
    "accounts": [
      "Google Cloud (calendar sync, optional)"
    ],
    "active": true,
    "lastActivity": "2026-09-02",
    "gotchas": [
      "GPL-3.0 copyleft; removing branding for resale is a separate white-label license on easyappointments.org/premium",
      "API auth is admin basic auth or an API key set in Settings; the docs insist on HTTPS",
      "Named repeatedly as the fallback in the April 2026 'Cal.com is going closed source' thread, so expect issue traffic from migrating users"
    ],
    "fit": {
      "adaptable": 2,
      "operable": 3
    },
    "evidence": {
      "formFactor": "README: self-hosted PHP web application, Apache or Nginx, MySQL",
      "executionModel": "no model SDK or AI feature",
      "operability": "docs/rest-api.md and openapi.yml in the Builder's repo; bearer API key or basic auth",
      "effort": "config-sample.php constants read this run; docs/docker.md maps the same names to environment variables",
      "editions": "README: GPL v3 code, free for commercial use; easyappointments.org/premium lists paid services with quotes, no list prices",
      "active": "shortlist pushedAt 2026-09-02"
    },
    "confidence": {
      "formFactor": 0.95,
      "executionModel": 0.95,
      "operability": 0.95,
      "effort": 0.9,
      "reach": 0.85,
      "editions": 0.8
    },
    "openQuestions": [
      "Do API-created appointments trigger customer and provider notification emails?",
      "Does the providers resource expose the working plan and booking rules for editing?"
    ],
    "sources": [
      {
        "url": "https://github.com/alextselegidis/easyappointments",
        "foundBy": "sourcing:scheduling-staffing:community"
      },
      {
        "url": "https://news.ycombinator.com/item?id=47780456",
        "foundBy": "sourcing:scheduling-staffing:community"
      },
      {
        "url": "https://github.com/alextselegidis/easyappointments/blob/master/docs/rest-api.md",
        "foundBy": "analysis:scheduling-staffing"
      },
      {
        "url": "https://easyappointments.org/premium",
        "foundBy": "analysis:scheduling-staffing"
      }
    ],
    "research": {
      "stage": "verified",
      "verdict": "unverified",
      "reason": "Official REST API with an OpenAPI file and near-complete Reach; single config.php surface; GPL caps adaptable at 2.",
      "disputed": []
    },
    "url": "apps/alextselegidis--easyappointments.html",
    "coverage": "partial",
    "paid": false,
    "source": "research/verified/alextselegidis--easyappointments.json"
  }
}
