feat(backend): attribute OpenRouter requests to the Platypus app - #427
Merged
Conversation
OpenRouter credits each request to an app via HTTP-Referer, which is what puts an app on its public model pages and rankings. Nothing supplied those headers, so Platypus usage went untracked unless an operator typed them into a Provider's Headers field by hand. Send HTTP-Referer, X-OpenRouter-Title and X-OpenRouter-Categories as defaults beneath a Provider's own headers. The Provider wins on collision, matched case-insensitively so a hand-written `http-referer` replaces the default rather than shipping a second referer. A blank referer in any casing is an explicit opt-out and drops all three. No environment variables: every other per-Provider knob lives on the Provider row, and the existing Headers field already gives per-Workspace override and opt-out, which env vars would only duplicate at coarser granularity. Documents the previously undocumented Provider Headers field along the way. Closes #426 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #426
What
OpenRouter credits each request to an app via
HTTP-Referer, and that credit is what puts an app on its public model pages and rankings. Platypus sent nothing, so usage went untracked unless an operator hand-typed the headers into a Provider's Headers field.OpenRouter Providers now send three attribution headers by default:
HTTP-Refererhttps://github.com/willdady/platypusX-OpenRouter-TitlePlatypusX-OpenRouter-Categoriespersonal-agent,general-chatThese are defaults, not policy. A Provider's own
headerswin, matched case-insensitively so a hand-writtenhttp-refererreplaces the default rather than shipping a second referer. A blank referer in any casing is an explicit opt-out and drops all three, while leaving unrelated custom headers alone.Header names and both category slugs were verified against OpenRouter's app-attribution docs.
Deliberately no environment variables
The issue proposed
OPENROUTER_HTTP_REFERER/OPENROUTER_APP_TITLE/OPENROUTER_APP_CATEGORIES. Rejected during triage: every other per-Provider knob (API key, base URL, headers, extra body, region) lives on the Provider row, which is scoped to an Organization or Workspace, while backend env vars here are deploy-time infrastructure. The existing Headers field already provides override and opt-out — at finer granularity than env vars would. No schema change, no form change, no new config surface.Notes for review
HTTP-Refererhide an earlier blankhttp-refererand silently keep attribution on.headersis jsonb, cast rather than parsed on read, so a value can be a non-string at runtime despite the type. A malformed row passes through as before instead of throwing on every model call.Docs
Documents the Provider Headers field, which was previously undocumented — headers were covered for MCPs and Webhooks but not Providers — plus the attribution defaults and how to re-attribute or opt out.
Testing
pnpm test— 1513 backend tests pass, 8/8 taskspnpm typecheckandpnpm lintcleanNot verified: that requests appear under the Platypus app in the OpenRouter dashboard. That needs a real account and actual spend — a manual post-merge check.
🤖 Generated with Claude Code