{"id":41777844,"url":"https://github.com/teklynk/twitch_api_public","last_synced_at":"2026-02-17T06:18:51.623Z","repository":{"id":91755738,"uuid":"457233060","full_name":"teklynk/twitch_api_public","owner":"teklynk","description":"Simple PHP Twitch API Gateway that only requires the user/channel name to return data","archived":false,"fork":false,"pushed_at":"2026-02-15T23:34:11.000Z","size":233,"stargazers_count":7,"open_issues_count":0,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2026-02-16T06:48:45.076Z","etag":null,"topics":["api","api-gateway","api-server","twitch"],"latest_commit_sha":null,"homepage":"https://twitchapi.teklynk.com/docs/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/teklynk.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"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},"funding":{"github":["teklynk"],"liberapay":"teklynkliberapay","ko_fi":"teklynk","custom":["https://www.paypal.com/donate/?hosted_button_id=UVKZUYFMXQDPL"]}},"created_at":"2022-02-09T06:16:07.000Z","updated_at":"2025-09-25T19:08:35.000Z","dependencies_parsed_at":null,"dependency_job_id":"c773d644-be42-4137-9fd1-d874d13e906c","html_url":"https://github.com/teklynk/twitch_api_public","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/teklynk/twitch_api_public","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teklynk%2Ftwitch_api_public","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teklynk%2Ftwitch_api_public/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teklynk%2Ftwitch_api_public/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teklynk%2Ftwitch_api_public/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/teklynk","download_url":"https://codeload.github.com/teklynk/twitch_api_public/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/teklynk%2Ftwitch_api_public/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29535934,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-17T05:00:25.817Z","status":"ssl_error","status_checked_at":"2026-02-17T04:57:16.126Z","response_time":100,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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","api-gateway","api-server","twitch"],"created_at":"2026-01-25T03:33:04.283Z","updated_at":"2026-02-17T06:18:51.596Z","avatar_url":"https://github.com/teklynk.png","language":"PHP","funding_links":["https://github.com/sponsors/teklynk","https://liberapay.com/teklynkliberapay","https://ko-fi.com/teklynk","https://www.paypal.com/donate/?hosted_button_id=UVKZUYFMXQDPL"],"categories":[],"sub_categories":[],"readme":"# Twitch API Public Gateway\n\n## Overview\n\nThis is a way to run your own Twitch API \"gate-way\" service that only requires the user name/channel name to pull data. It acts as a public gateway to Twitch's API. This is useful when creating your own Twitch tools/apps and just want to get data from Twitch without passing in your client id and auth token into your code and manually refreshing your auth token every 3 months. Auth token automatically refreshes on the server every day. All requests use GET to pull data. Nothing is posted back to Twitch and nothing is stored on the server. Once set up, getting data from Twitch is as simple as going to a URL and parsing the returned JSON string.\n\n## Recent Updates\n\n### June 2024\n`getuserclips.php` can now be filtered by \"is_featured\". This will show clips that the channel has set as Featured.\nExample: `https://example.com/getuserclips.php?channel=MrCoolStreamer\u0026prefer_featured=true\u0026limit=100`\n\n### September 2023\nFollows and Following endpoint now require a user access token and client ID that includes the `user:read:follows` and/or `moderator:read:followers` scope. This can be generated from twitchtokengenerator.com. The access token and client ID can then be used in the endpoint url: `https://example.com/getuserfollowing.php?channel=MrCoolStreamer\u0026limit=100\u0026ref=accessTokenXyz123Abc\u0026clientId=abc123xyz5678`\n\nThe access token and client ID values need to be base_64 encoded.\n- javascript: `btoa(stringToEncode);`\n- php: `base64_encode(stringToEncode);`\n\nThe JSON format for \"followers\" and \"followed\" has also changed. Please refer to: Twitch API Reference\n\n## Installation\n\n### Option 1: Using Docker (Recommended)\n\nThis branch includes a `Dockerfile` and `docker-compose.yml` to easily run the application locally or on a server.\n\n1.  **Clone the repository:**\n    ```bash\n    git clone \u003crepository-url\u003e\n    cd twitch_api_public\n    ```\n\n2.  **Configure Environment:**\n    Rename `sample.env` to `.env` and add your Twitch Client ID and Secret.\n    ```bash\n    cp sample.env .env\n    ```\n    *See Configuration below for details on getting Twitch credentials.*\n\n3.  **Build and Run:**\n    ```bash\n    docker-compose up -d --build\n    ```\n    This will start the Nginx, PHP-FPM, and Memcached containers.\n\n4.  **Access the API:**\n    The API should now be accessible at `http://localhost:8080` (or your server's IP).\n\n**Docker Notes:**\n- **Memcached:** If using Docker, ensure `getuserclips.php` is configured to connect to the `memcached` container host instead of `127.0.0.1`.\n- **Stopping:** To stop the containers, run `docker-compose down`.\n\n### Option 2: Manual Installation (Bare Metal)\n\nIf you prefer not to use Docker, you can run this on a standard LAMP/LEMP stack.\n\n#### 1. Prerequisites\n- Linux server (Ubuntu/Debian recommended)\n- Nginx or Apache\n- PHP 8.1+ (with cURL, XML, mbstring extensions)\n- Composer\n- Memcached\n\n#### 2. Install Dependencies (Ubuntu Example)\n\n**Install PHP and Extensions:**\n```bash\nsudo apt update\nsudo apt install -y php-fpm php-curl php-xml php-mbstring\n```\n\n**Install Memcached:**\n```bash\nsudo apt install -y memcached php-memcached libmemcached-dev\nsudo service memcached start\n```\n\n**Install Composer:**\n```bash\ncurl -sS https://getcomposer.org/installer -o composer-setup.php\nsudo php composer-setup.php --install-dir=/usr/local/bin --filename=composer\nrm composer-setup.php\n```\n\n#### 3. Project Setup\n\n1.  **Clone the repository:**\n    ```bash\n    cd /var/www/html\n    git clone \u003crepository-url\u003e\n    cd twitch_api_public\n    ```\n\n2.  **Install PHP Packages:**\n    ```bash\n    composer install\n    ```\n\n3.  **Configure Environment:**\n    ```bash\n    cp sample.env .env\n    ```\n    Edit `.env` and add your Twitch credentials.\n\n#### 4. Web Server Configuration\n\nSet the web site's root directory in the nginx/apache config to `/var/www/html/twitch_api_public/public`.\n\n**NGINX Config Example:**\n```nginx\nserver {\n    server_name    example.com;\n    root           /var/www/html/twitch_api_public/public;\n    index          index.php;\n\n    add_header Access-Control-Allow-Origin *;\n\n    # Deny access to . files, for security\n    location ~ /\\. {\n      log_not_found off;\n      deny all;\n    }\n\n    location / {\n      try_files $uri $uri/ =404;\n    }\n\n    location ~* \\.php$ {\n      fastcgi_pass unix:/run/php/php8.1-fpm.sock; # Adjust version as needed\n      include         fastcgi_params;\n      fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;\n      fastcgi_param   SCRIPT_NAME        $fastcgi_script_name;\n    }\n\n    # SSL Configuration (Managed by Certbot recommended)\n    listen 80;\n    listen [::]:80;\n}\n```\n\n## APACHE Config Example\n```apache\n\u003cVirtualHost *:443\u003e\n   DocumentRoot /var/www/html/twitch_api_public/public\n   ServerName example.com;\n\n   ErrorLog ${APACHE_LOG_DIR}/error.log\n   CustomLog ${APACHE_LOG_DIR}/access.log combined\n\n   \u003cDirectory \"/var/www/html/twitch_api_public/public\"\u003e\n        Options Indexes FollowSymLinks MultiViews\n        AllowOverride All\n        Require all granted\n   \n        DirectoryIndex index.php\n        RewriteEngine On\n\n        RewriteCond %{REQUEST_FILENAME} !-d\n        RewriteCond %{REQUEST_FILENAME} !-f\n        RewriteRule ^[^.]+$ index.php [L]\n   \u003c/Directory\u003e\n   \n   SSLEngine on\n\n   SSLCertificateFile /etc/apache2/certificate/apache2.crt\n   SSLCertificateKeyFile /etc/apache2/certificate/private.key\n\u003c/VirtualHost\u003e\n```\n\n## Instructions and Notes\n\n- **Rename** sample.env to .env\n\n- Visit https://dev.twitch.tv/ to register your application. \n- On the dev.twitch.tv site, click \"Your Console\" in the upper right. Under \"Applications\" click \"Register Your Application\". \n- Give your Application a Name.\n- OAuth Redirect URLs. When testing locally, you can set this to http://localhost. I like to add localhost and my public domain name entry. This will allow your domain(s) access to the Twitch API. (These domains with this OAuth token and client ID are allowed to access the Twitch API)\n- Select Category \u003e Chat Bot.\n\n- Add your Twitch client ID and Twitch secret to the .env file.\n\nThese files are needed to generate your Twitch oAuth token.\n\n## Getting data\n\nRequests are returned in JSON format so that you can parse the data as needed. Some requests require a limit parameter in the url and have a max limit of 100.\n\n## Example Requests\n\nPagination is possible with \u0026after=cursor_value and \u0026before=cursor_value\nYou can get the cursor value from the first request.\n```json\n\"pagination\": {\n  \"cursor\": \"eyJiIjpudWxsLCJhIjp7IkN1cnNvciI6Ik1UQXkifX0\"\n}\n```\nExample: \n`https://example.com/getuserfollows.php?channel=MrCoolStreamer\u0026limit=100\u0026after=eyJiIjpudWxsLCJhIjp7IkN1cnNvciI6Ik1UQXkifX0`\nwill pull the next 100 follows.\n\n*Pull a single Random clip with: `\u0026random=true`. Set the `count=3` value to limit how many random clips are returned. If not set, then only 1 random clip is returned.\n\nExample: `https://example.com/getuserclips.php?channel=MrCoolStreamer\u0026limit=100\u0026random=true\u0026count=3`\n\n*Pull a single clip by its ID: id=DelightfulSuaveMacaroniNerfRedBlaster-2Z8TW9kD4d7jN_uy\n\nExample: `https://example.com/getuserclips.php?id=DelightfulSuaveMacaroniNerfRedBlaster-2Z8TW9kD4d7jN_uy`\n\n*Pull only featured clips\n\nExample: `https://example.com/getuserclips.php?channel=MrCoolStreamer\u0026prefer_featured=true\u0026limit=100`\n\n*Ignore / skip newer Twitch clip URLs. `\u0026ignore=new`\n\n\n## End points examples:\n\n`https://example.com/getuserstatus.php?channel=MrCoolStreamer`\n\n`https://example.com/getuserinfo.php?channel=MrCoolStreamer`\n\n`https://example.com/getstream.php?channel=MrCoolStreamer`\n\n`https://example.com/getuserfollows.php?channel=MrCoolStreamer\u0026limit=100\u0026ref=accesstokenxyz123\u0026clientId=abc123xyz5678`\n\n`https://example.com/getuserfollowing.php?channel=MrCoolStreamer\u0026limit=100\u0026ref=accesstokenxyz123\u0026clientId=abc123xyz5678`\n\n`https://example.com/getuseremotes.php?channel=MrCoolStreamer\u0026limit=100`\n\n`https://example.com/getglobalemotes.php`\n\n`https://example.com/getuserclips.php?channel=MrCoolStreamer\u0026limit=100`\n\n`https://example.com/getuserclips.php?channel=MrCoolStreamer\u0026limit=100\u0026start_date=2023-02-15T00:00:00Z\u0026end_date=2023-02-24T00:00:00Z\u0026creator_name=MrCoolStreamer`\n\n`https://example.com/getuserclips.php?channel=MrCoolStreamer\u0026prefer_featured=true\u0026limit=100`\n\n`https://example.com/getviewers.php?channel=MrCoolStreamer`\n\n`https://example.com/getgame.php?id=23123`\n\n`https://example.com/getuserschedule.php?channel=MrCoolStreamer`\n\n`https://example.com/getuserschedule.php?channel=MrCoolStreamer\u0026ical=true` - returns .ics download file that can imported into a calendar client.\n\n`https://example.com/getuserschedule.php?channel=MrCoolStreamer\u0026html=true\u0026format=0\u0026limit=30` - returns html view (format=1 is an alternate date/time format). Event dates and times have been converted to your local time zone. This could be used as a OBS browser source or embedded as an iframe on a website.\n\n`https://example.com/getbttvemotes.php?channel=MrCoolStreamer`\n\n**Most endpoints can use 'id' instead of 'channel'. Examples: `https://example.com/getuserinfo.php?id=55184769`, `https://example.com/getuserstatus.php?id=55184769`, `https://example.com/getuserschedule.php?id=55184769`**\n\njQuery Ajax Example:\n\n```javascript\nlet channel = \"MrCoolStreamer\";\n$.ajax({url: \"https://example.com/getuserinfo.php?channel=\" + channel, success: function(result) {\n\tconsole.log(result);\n}});\n\n// Example2: Json data - Ajax call\nlet clips_json = JSON.parse($.getJSON({\n\t'url': \"https://example.com/getuserclips.php?channel=\" + channel + \"\u0026limit=100\",\n\t'async': false\n}).responseText);\n\nconsole.log(clips_json.data[0]['thumbnail_url']);\n```\n\nJavaScript Example:\n\n```javascript\nlet getUserInfo = function (channel) {\n    let url = \"https://example.com/getuserinfo.php?channel=\" + channel;\n    return fetch(url)\n        .then(response =\u003e response.json());\n};\n\ngetUserInfo(\"MrCoolStreamer\").then(result =\u003e {\n\tconsole.log(result);\n});\n```\n\nCURL Example:\n\n```bash\ncurl -X GET 'https://example.com/getuserinfo.php?channel=MrCoolStreamer'\n```\n\nPHP using CURL Example:\n\n```php\n$ch = curl_init();\ncurl_setopt($ch, CURLOPT_URL, \"https://example.com/getuserinfo.php?channel=MrCoolStreamer\");\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n$result = curl_exec($ch);\ncurl_close($ch);\nvar_dump($result);\n```\n\nExample Responses:\n\n```json\n{\n  \"data\": [\n    {\n      \"id\": \"141981764\",\n      \"login\": \"mrcoolstreamer\",\n      \"display_name\": \"MrCoolStreamer\",\n      \"type\": \"\",\n      \"broadcaster_type\": \"partner\",\n      \"description\": \"Supporting third-party developers building Twitch integrations from chatbots to game integrations.\",\n      \"profile_image_url\": \"https://static-cdn.jtvnw.net/jtv_user_pictures/8a6381c7-d0c0-4576-b179-38bd5ce1d6af-profile_image-300x300.png\",\n      \"offline_image_url\": \"https://static-cdn.jtvnw.net/jtv_user_pictures/3f13ab61-ec78-4fe6-8481-8682cb3b0ac2-channel_offline_image-1920x1080.png\",\n      \"view_count\": 5980557,\n      \"created_at\": \"2016-12-14T20:32:28Z\"\n    }\n  ]\n}\n```\n## Clips\ngetuserclips.php\n\n```json\n{\n  \"data\": [\n    {\n      \"item\": 22,\n      \"id\": \"VictoriousAwkwardPheasantKevinTurtle-xT8tH7fW0oU0vZ8gT4\",\n      \"url\": \"https://clips.twitch.tv/VictoriousAwkwardPheasantKevinTurtle-xT8tH7fW0oU0vZ8gT4\",\n      \"embed_url\": \"https://clips.twitch.tv/embed?clip=VictoriousAwkwardPheasantKevinTurtle-xT8tH7fW0oU0vZ8gT4\",\n      \"broadcaster_id\": \"159805577\",\n      \"broadcaster_name\": \"Teklynk\",\n      \"creator_id\": \"141981764\",\n      \"creator_name\": \"MrCoolStreamer\",\n      \"video_id\": \"\",\n      \"game_id\": \"509670\",\n      \"language\": \"en\",\n      \"title\": \"I don't know what is happening\",\n      \"view_count\": 1,\n      \"created_at\": \"2022-08-08T17:33:04Z\",\n      \"thumbnail_url\": \"https://clips-media-assets2.twitch.tv/_tduXpTTRFVsBuTb_XYZABC/vod-1543945678-offset-4866-preview-480x272.jpg\",\n      \"duration\": 30,\n      \"vod_offset\": null,\n      \"clip_url\": \"https://clips-media-assets2.twitch.tv/_tduXpTTRFVsBuTb_XYZABC/vod-1543945678-offset-4866.mp4\"\n    }\n  ]\n}\n```\n\n## BetterTTV Emotes\ngetbttvemotes.php\n```json\n[\n  {\n    \"id\": \"636ff60fb9076d0aaebbcf7c\",\n    \"code\": \"Tekbot\"\n  },\n  {\n    \"id\": \"5ba6d5ba6ee0c23989d52b10\",\n    \"code\": \"bongoTap\"\n  },\n  {\n    \"id\": \"5a6edb51f730010d194bdd46\",\n    \"code\": \"PepoDance\"\n  },\n  {\n    \"id\": \"5d922afbc0652668c9e52ead\",\n    \"code\": \"peepoArrive\"\n  },\n  {\n    \"id\": \"59f06613ba7cdd47e9a4cad2\",\n    \"code\": \"PartyParrot\"\n  },\n  {\n    \"id\": \"5c3427a55752683d16e409d1\",\n    \"code\": \"peepoPooPoo\"\n  },\n  {\n    \"id\": \"5bc7ff14664a3b079648dd66\",\n    \"code\": \"peepoRun\"\n  },\n  {\n    \"id\": \"5df2d1b7e7df1277b6070b1e\",\n    \"code\": \"pepeJAM\"\n  },\n  {\n    \"id\": \"5f21e57a65fe924464eecf0e\",\n    \"code\": \"catRAVE\"\n  },\n  {\n    \"id\": \"54fa8f1401e468494b85b537\",\n    \"code\": \":tf:\"\n  }\n]\n```\nBTTV Emote URL: https://cdn.betterttv.net/emote/5a970ab2122e4331029f0d7e/3x","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteklynk%2Ftwitch_api_public","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fteklynk%2Ftwitch_api_public","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fteklynk%2Ftwitch_api_public/lists"}