{"id":50671678,"url":"https://github.com/osu-community-tournaments/osu-api-proxy","last_synced_at":"2026-06-25T09:00:32.092Z","repository":{"id":358143655,"uuid":"1240200562","full_name":"osu-community-tournaments/osu-api-proxy","owner":"osu-community-tournaments","description":"A proxy for osu! api for tournament spreadsheets","archived":false,"fork":false,"pushed_at":"2026-05-15T23:42:51.000Z","size":21,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-16T00:53:20.053Z","etag":null,"topics":["osu","osu-api","osu-tournament","osu-tourney"],"latest_commit_sha":null,"homepage":"","language":null,"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/osu-community-tournaments.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"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}},"created_at":"2026-05-15T21:48:37.000Z","updated_at":"2026-05-15T23:42:55.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/osu-community-tournaments/osu-api-proxy","commit_stats":null,"previous_names":["osu-community-tournaments/osu-api-proxy"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/osu-community-tournaments/osu-api-proxy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osu-community-tournaments%2Fosu-api-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osu-community-tournaments%2Fosu-api-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osu-community-tournaments%2Fosu-api-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osu-community-tournaments%2Fosu-api-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/osu-community-tournaments","download_url":"https://codeload.github.com/osu-community-tournaments/osu-api-proxy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/osu-community-tournaments%2Fosu-api-proxy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34767548,"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-25T02:00:05.521Z","response_time":101,"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":["osu","osu-api","osu-tournament","osu-tourney"],"created_at":"2026-06-08T12:00:22.020Z","updated_at":"2026-06-25T09:00:32.072Z","avatar_url":"https://github.com/osu-community-tournaments.png","language":null,"funding_links":[],"categories":["Community Resources"],"sub_categories":["Google Sheets Templates"],"readme":"# osu! API Proxy (pure nginx)\n\n## What it does\n\n- Forwards `/api/*` and `/oauth/token` to `https://osu.ppy.sh`.\n- Rejects everything else with 404.\n- Applies `limit_req` rate limiting at 3 r/s (burst 10).\n- Optionally requires a shared secret via header or query string.\n- Strips Cloudflare-style headers (`CF-Connecting-IP`, `CF-Ray`, …) before\n  forwarding upstream.\n\n## Prerequisites\n\n- A Linux VPS with nginx (≥ 1.18 — anything modern).\n- A TLS cert for the chosen domain (Let's Encrypt / certbot / acme.sh / etc.).\n\n## Deploy\n\nThere are two flavors of the server block. Pick one.\n\n| File                          | When to use                                                      |\n|-------------------------------|------------------------------------------------------------------|\n| `nginx.conf.example`          | Open proxy. Network-level access control (firewall, private DNS). |\n| `nginx-secret.conf.example`   | Anyone can hit the domain; require a shared secret.              |\n\n### Steps\n\n1. **Copy configuration with your details** into `/etc/nginx/sites-available/osu-proxy.conf`.\n   Adjust `server_name` and `ssl_certificate*` to your domain.\n\n2. **Enable \u0026 reload:**\n\n   ```bash\n   ln -s /etc/nginx/sites-available/osu-proxy.conf /etc/nginx/sites-enabled/\n   nginx -t \u0026\u0026 systemctl reload nginx\n   ```\n\n3. **Verify:** `curl https://your.domain/health` → `{\"status\":\"ok\",...}`.\n\n## Authentication (secret variant)\n\nSend the secret in one of:\n\n| Method                | Example                                                                |\n|-----------------------|------------------------------------------------------------------------|\n| Header (recommended)  | `X-Proxy-Secret: your-secret-here`                                     |\n| Query param (API v2)  | `https://your.domain/api/v2/...?proxy_secret=your-secret`              |\n| Query param (API v1)  | `https://your.domain/api/get_beatmaps?k=KEY\u0026proxy_secret=your-secret`  |\n\nThe `proxy_secret` query parameter is stripped before the request is\nforwarded to osu.ppy.sh. The `X-Proxy-Secret` header is also stripped.\n\nThe secret lives in your nginx config. Keep that file readable only by\nnginx (`chmod 0640`, owned by root, group nginx).\n\n## Apps Script usage\n\nReplace all `https://osu.ppy.sh` with your proxy URL. If you use the secret\nvariant, add the header to every `UrlFetchApp` call:\n\n```js\nvar options = {\n  method: \"get\",\n  headers: {\n    \"Authorization\": \"Bearer \" + osuToken,\n    \"X-Proxy-Secret\": \"your-secret-here\"\n  }\n};\nvar response = UrlFetchApp.fetch(url, options);\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosu-community-tournaments%2Fosu-api-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fosu-community-tournaments%2Fosu-api-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fosu-community-tournaments%2Fosu-api-proxy/lists"}