{"id":50646122,"url":"https://github.com/xsga/filmaffinity-api","last_synced_at":"2026-06-24T09:00:47.370Z","repository":{"id":241602354,"uuid":"283606713","full_name":"xsga/filmaffinity-api","owner":"xsga","description":"FilmAffinity-API is a public and non official API wich allow you to get information about films from FilmAffinity website. You can search films and get their complet information, including cast, synopsis and cover.","archived":false,"fork":false,"pushed_at":"2025-10-28T16:42:23.000Z","size":804,"stargazers_count":24,"open_issues_count":0,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-28T18:30:33.990Z","etag":null,"topics":["api","docker","docker-compose","dockerfile","filmaffinity","filmaffinity-api","php","slim-4","slim-framework"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/xsga.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2020-07-29T21:33:15.000Z","updated_at":"2025-10-28T16:38:43.000Z","dependencies_parsed_at":"2025-10-28T18:17:09.742Z","dependency_job_id":"a8cf00ef-d82c-465d-819b-a97e1be2343a","html_url":"https://github.com/xsga/filmaffinity-api","commit_stats":null,"previous_names":["xsga/filmaffinity-api"],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/xsga/filmaffinity-api","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xsga%2Ffilmaffinity-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xsga%2Ffilmaffinity-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xsga%2Ffilmaffinity-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xsga%2Ffilmaffinity-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/xsga","download_url":"https://codeload.github.com/xsga/filmaffinity-api/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/xsga%2Ffilmaffinity-api/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34724743,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-24T02:00:07.484Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","docker","docker-compose","dockerfile","filmaffinity","filmaffinity-api","php","slim-4","slim-framework"],"created_at":"2026-06-07T13:00:29.297Z","updated_at":"2026-06-24T09:00:47.364Z","avatar_url":"https://github.com/xsga.png","language":"PHP","funding_links":[],"categories":["Cine y Entretenimiento"],"sub_categories":["FilmAffinity"],"readme":"# filmaffinity-API\n\n[![Language](https://img.shields.io/github/languages/top/xsga/filmaffinity-api)](https://php.net/)\n[![Minimum PHP Version](https://img.shields.io/badge/php-%3E%3D%208.4-8892BF?style=flat)](https://php.net/)\n[![Latest version](https://img.shields.io/github/v/release/xsga/filmaffinity-api)](https://github.com/xsga/filmaffinity-api/releases/tag/v7.2.0)\n[![License](https://img.shields.io/github/license/xsga/filmaffinity-api)](https://opensource.org/licenses/MIT)\n\nFilmAffinity-API is a public and non offical API wich allow you to get information about films from [FilmAffinity](http://filmaffinity.com \"FilmAffinity Home\") website. You can search films and get their complet  information, including cast, synopsis and cover.\n\nThis API is written in PHP and uses Slim 4 framework.\n\n\n### ⚠️ IMPORTANT NOTE: FilmAffinity Anti-Bot Protection ###\n\nFilmAffinity currently implements anti-bot protection (Cloudflare or similar services like Akamai) that requires JavaScript execution and dynamically generated session cookies. This means:\n\n- The FilmAffinity server does not return the real HTML content directly\n- Instead, it serves a challenge page that your browser solves by executing JavaScript\n- Session cookies are generated dynamically only after solving the challenge\n- HTTP clients without a JavaScript engine (Guzzle, cURL, etc.) receive only the error/challenge page\n\n**This is why web scrapers and API clients that don't execute JavaScript fail to retrieve film data from FilmAffinity.** To work around this limitation, you would need to use tools like:\n- Puppeteer or Playwright (Node.js)\n- Selenium or Playwright (Python)\n- Headless browser solutions with JavaScript rendering capabilities\n- Third-party scraping services: [Prerender.io](https://prerender.io), [ScraperAPI](https://www.scraperapi.com), [Apify](https://apify.com), or similar services that handle JavaScript rendering and bot protection challenges\n\n\n## Technology Stack \u0026 Dependencies\n\n**Core Framework \u0026 HTTP:**\n- [Slim 4](https://www.slimframework.com/) - Lightweight PHP microframework\n- [Guzzle HTTP Client](https://docs.guzzlephp.org/) - PHP HTTP client for making requests\n\n**Database \u0026 ORM:**\n- [Doctrine ORM](https://www.doctrine-project.org/projects/orm.html) - Object-Relational Mapping\n- MySQL database\n\n**Dependency Injection \u0026 Configuration:**\n- [PHP-DI](https://php-di.org/) - Container for dependency injection\n- [vlucas/phpdotenv](https://github.com/vlucas/phpdotenv) - Environment variables management\n\n**Authentication \u0026 Security:**\n- [Firebase JWT](https://github.com/firebase/php-jwt) - JWT token handling for API authentication\n\n**Validation \u0026 Schema:**\n- [Swaggest JSON Schema](https://github.com/swaggest/json-schema) - JSON schema validation\n\n**Console \u0026 Commands:**\n- [Symfony Console](https://symfony.com/doc/current/components/console.html) - CLI commands framework\n\n**Caching:**\n- [Symfony Cache](https://symfony.com/doc/current/components/cache.html) - Application caching\n\n---\n\n## Install with Docker Compose\n\nPrerequisites:\n\n* Docker.\n* Docker Desktop (optional)\n\nInstructions:\n\n* Run `docker compose` to star Docker container and inits system.\n```\ndocker compose up -d\n```\n* Run `composer install` to install the project dependencies:\n```\ncomposer install\n```\n* Rename `config/.env.example` to `config/.env` to activates environment settings.\n* Setup API settings edditing `config/.env` file (don't change `URL_PATH` and database variables).\n* Use test user (email `test@test.com` and password `test`) or create a user using command `app:create-user`:\n```\ndocker exec -it filmaffinityapi-web-server php .bin/console app:create-user\n```\n* FilmAffinityAPI is available at the following URL: `http://localhost/app`\n\n\n## Manual installation\n\nPrerequisites:\n\n* PHP 8.3 or later.\n* PHP libraries `mbstring`,  `zip`, `gd`, `pdo_mysql`, `sockets` and `apcu` installed.\n* Apache's `mod_rewrite` and `mod_headers` modules enabled.\n* Composer\n\nInstructions:\n\n* Unzip the API files in an empty folder in your server.\n* Make sure that the HTTP shared folder match with the API `public` folder.\n* `log`, `tmp` and `data` folders and subfolders needs read and write permissions:\n```\nchmod 777 -R log\nchmod 777 -R tmp\nchmod 777 -R data\n```\n* Run `composer install` to install the project dependencies:\n```\ncomposer install\n```\n* Rename `config/.env.example` to `config/.env` to activates environment settings.\n* Setup API settings edditing `config/.env` file.\n* Create a MySQL database and run scripts under folder `scripts` to create database structure.\n* Create a user using command `app:create-user`:\n```\nphp .bin/console app:create-user\n```\n\n\n## API public methods\n\nThe API has the following public methods:\n\n|Method name|HTTP method|API endpoint|Body|\n|-----------|-----------|------------|----|\n|Get user token|POST|users/token|[JSON Schema](https://github.com/xsga/filmaffinity-api/blob/master/config/schemas/input/get.token.schema.json)|\n|Simple films search|POST|searches/simple|[JSON Schema](https://github.com/xsga/filmaffinity-api/blob/master/config/schemas/input/simple.search.schema.json)|\n|Advanced films search|POST|searches/advanced|[JSON Schema](https://github.com/xsga/filmaffinity-api/blob/master/config/schemas/input/advanced.search.schema.json)|\n|Get film information|GET|films/:id|-|\n|Get genres|GET|genres|-|\n|Get countries|GET|countries|-|\n\n\n## Console commands\n\nSystem provides some Symfony console commands:\n\n|Command|Command description|\n|-------|------------|\n`app:create-user`|Create a new user|\n`app:delete-user`|Delete a user|\n`app:disable-user`|Disable a user|\n`app:enable-user`|Enable a user|\n`app:get-password`|Get hashed password|\n`app:get-token`|Get JWT user token|\n`app:backup-countries`|FilmAffinity countries backup (store in `data/backup` folder)|\n`app:backup-genres`|FilmAffinity genres backup (store in `data/backup` folder)|\n\nTo executes a command, run the following command:\n```\nphp .bin/console \u003cCOMMAND\u003e\n```\n\nIn a docker environment, execute it into container:\n```\ndocker exec -it filmaffinityapi-web-server php .bin/console \u003cCOMMAND\u003e\n```\n\n## API basic usage examples\n\n### Simple films search\n**URL**\n```\n[GET] http://\u003cserver_domain_api\u003e/searches/simple\n```\n\n**INPUT**\n```json\n{\"text\": \"pulp fiction\"}\n```\n\n**OUTPUT**\n```json\n{\n  \"status\": \"OK\",\n  \"statusCode\": 200,\n  \"response\": {\n    \"total\": 2,\n    \"results\": [\n      {\n        \"id\": 160882,\n        \"title\": \"Pulp Fiction\",\n        \"year\": 1994,\n        \"directors\": [\"Quentin Taratino\"]\n      },\n      {\n        \"id\": 991349,\n        \"title\": \"8 Bit Cinema: Pulp Fiction\",\n        \"year\": 2014,\n        \"directors\": [\"David Dutton\"]\n      }\n    ]\n  }\n}\n```\n\n### Advanced films search\n\n**EXAMPLE 1:** An example of an advanced search searching only for a text in the title of the film.\n\n**URL**\n```\n[POST] http://\u003cserver_domain_api\u003e/searches/advanced\n```\n\n**INPUT**\n```json\n{\n  \"text\": \"pulp fiction\",\n  \"search_in_title\": true,\n  \"search_in_director\": false,\n  \"search_in_cast\": false,\n  \"search_in_screenplay\": false,\n  \"search_in_photography\": false,\n  \"search_in_soundtrack\": false,\n  \"search_in_producer\": false,\n  \"country\": \"\",\n  \"genre\": \"\",\n  \"year_from\": 0,\n  \"year_to\": 0\n}\n```\n\n**OUTPUT**\n```json\n{\n  \"status\": \"OK\",\n  \"statusCode\": 200,\n  \"response\": {\n    \"total\": 1,\n    \"results\": [\n      {\n        \"id\": 160882,\n        \"title\": \"Pulp Fiction\",\n        \"year\": 1994,\n        \"directors\": [\"Quentin Taratino\"]\n      },\n      {\n        \"id\": 991349,\n        \"title\": \"8 Bit Cinema: Pulp Fiction\",\n        \"year\": 2014,\n        \"directors\": [\"David Dutton\"]\n      }\n    ]\n  }\n}\n```\n\n**EXAMPLE 2:** another example of an advanced search searching for a text in the title of the film and between two years.\n\n**URL**\n```\n[POST] http://\u003cserver_domain_api\u003e/searches/advanced\n```\n\n**INPUT**\n```json\n{\n  \"text\": \"pulp fiction\",\n  \"search_in_title\": true,\n  \"search_in_director\": false,\n  \"search_in_cast\": false,\n  \"search_in_screenplay\": false,\n  \"search_in_photography\": false,\n  \"search_in_soundtrack\": false,\n  \"search_in_producer\": false,\n  \"country\": \"\",\n  \"genre\": \"\",\n  \"year_from\": 1992,\n  \"year_to\": 2000\n}\n```\n\n**OUTPUT**\n```json\n{\n  \"status\": \"OK\",\n  \"statusCode\": 200,\n  \"response\": {\n    \"total\": 1,\n    \"results\": [\n      {\n        \"id\": 160882,\n        \"title\": \"Pulp Fiction\",\n        \"year\": 1994,\n        \"directors\": [\"Quentin Taratino\"]\n      }\n    ]\n  }\n}\n```\n\n### Get film information\n**URL**\n```\n[GET] http://\u003cserver_domain_api\u003e/films/160882\n```\n\n**OUTPUT**\n```json\n{\n  \"status\": \"OK\",\n  \"statusCode\": 200,\n  \"response\": {\n    \"filmAfinityId\": \"160882\",\n    \"title\": \"Pulp Fiction\",\n    \"originalTitle\": \"Pulp Fiction\",\n    \"year\": 1994,\n    \"duration\": 153,\n    \"coverUrl\": \"https://pics.filmaffinity.com/pulp_fiction-210382116-large.jpg\",\n    \"coverFile\": \"pulp_fiction-210382116-large.jpg\",\n    \"rating\": \"8,6\",\n    \"country\": \"Estados Unidos\",\n    \"directors\": [\"Quentin Tarantino\"],\n    \"screenplay\": \"Quentin Tarantino, Roger Avary\",\n    \"soundtrack\": \"Varios\",\n    \"photography\": \"Andrzej Sekula\",\n    \"cast\": [\"John Travolta\", \"Samuel L. Jackson\", \"Uma Thurman\", \"Bruce Willis\", \"Ving Rhames\", \"Harvey Keitel\", \"Tim Roth\", \"Amanda Plummer\", \"María de Medeiros\", \"Eric Stoltz\", \"Rosanna Arquette\", \"Christopher Walken\", \"Paul Calderon\", \"Bronagh Gallagher\", \"Peter Greene\", \"Stephen Hibbert\", \"Angela Jones\", \"Phil LaMarr\", \"Robert Ruth\", \"Julia Sweeney\", \"Quentin Tarantino\", \"Frank Whaley\", \"Duane Whitaker\", \"Steve Buscemi\", \"Burr Steers\"],\n    \"producer\": \"Miramax, Band Apart, Jersey Films. Lawrence Bender\",\n    \"genres\": [\"Thriller\"],\n    \"genreTopics\": [\"Crimen\", \"Historias cruzadas\", \"Película de culto\", \"Comedia negra\"],\n    \"synopsis\": \"Jules y Vincent, dos asesinos a sueldo con no demasiadas luces, trabajan para el gángster Marsellus Wallace. Vincent le confiesa a Jules que Marsellus le ha pedido que cuide de Mia, su atractiva mujer. Jules le recomienda prudencia porque es muy peligroso sobrepasarse con la novia del jefe. Cuando llega la hora de trabajar, ambos deben ponerse \\\"manos a la obra\\\". Su misión: recuperar un misterioso maletín.\"\n  }\n}\n```\n\n### Get genres\n**URL**\n```\n[GET] http://\u003cserver_domain_api\u003e/genres\n```\n\n**OUTPUT**\n```json\n{\n  \"status\": \"OK\",\n  \"statusCode\": 200,\n  \"response\": [\n    {\n      \"code\": \"AC\",\n      \"description\": \"Acción\"\n    },\n    {\n      \"code\": \"AN\",\n      \"description\": \"Animación\"\n    },\n    {\n      \"code\": \"AV\",\n      \"description\": \"Aventuras\"\n    },\n    {\n      \"code\": \"BE\",\n      \"description\": \"Bélico\"\n    }\n  ]\n}\n```\n\n### Get countries\n**URL**\n```\n[GET] http://\u003cserver_domain_api\u003e/countries\n```\n\n**OUTPUT**\n```json\n{\n  \"status\": \"OK\",\n  \"statusCode\": 200,\n  \"response\": [\n    {\n      \"code\": \"AF\",\n      \"name\": \"Afganistán\"\n    },\n    {\n      \"code\": \"AL\",\n      \"name\": \"Albania\"\n    },\n    {\n      \"code\": \"DE\",\n      \"name\": \"Alemania\"\n    },\n    {\n      \"code\": \"FD\",\n      \"name\": \"Alemania del Este (RDA)\"\n    }\n  ]\n}\n```\n\nYou must inform the country/genre code in the body request of advances search if you want use these filters.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxsga%2Ffilmaffinity-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxsga%2Ffilmaffinity-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxsga%2Ffilmaffinity-api/lists"}