feat: add exact name filter to GET /api/organizations - #447
Merged
Merged
Conversation
Organizations can currently only be fetched through the API by UUID, so integrations that provision orgs programmatically cannot resolve an org from its human-readable name without hardcoding IDs (OHE-3156). Add an optional `name` query parameter to GET /api/organizations that narrows the listing to the caller's member organization with exactly that name. The match is exact and case-sensitive and is applied on top of the existing membership join, so a name the caller is not a member of yields an empty page instead of revealing that the org exists. An empty name is rejected with 422, and omitting the parameter keeps the current behavior. The filter is passed through OrgService.get_user_orgs_paginated and OrgStore.get_user_orgs_paginated, with tests at the store, service and route levels.
hieptl
marked this pull request as ready for review
September 21, 2026 10:43
Coverage reportClick to see where and how coverage changed
This report was generated by python-coverage-comment-action |
||||||||||||||||||||||||||||||
tofarr
approved these changes
Sep 22, 2026
tofarr
left a comment
Contributor
There was a problem hiding this comment.
If we are following the pattern we use elsewhere in the app, we would use name__eq as the argument name - but I see we already have a user_id
Contributor
|
🍰 |
Contributor
|
🚀 Released in 1.63.0. |
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.
HUMAN:
AGENT:
Why
BuildOne provisions and manages orgs programmatically and needs to resolve an org by its human-readable name to wire up their provisioning and routing flows. Today the only way to fetch an org through the API is by UUID (
GET /api/organizations/{org_id}), so they would have to hardcode UUIDs.GET /api/organizationsalready lists the caller's orgs but has no way to narrow the result, so this adds an exact name filter to that endpoint instead of introducing a new route.Summary
GET /api/organizationsaccepts an optionalnamequery parameter (1-255 chars). When set, only the caller's member org with exactly that name is returned. The match is exact and case-sensitive, and it is applied on top of the existing membership join, so a name the caller is not a member of returns an empty page instead of revealing that the org exists.?name=returns 422. Leavingnameout keeps the current behavior.nameis passed throughOrgService.get_user_orgs_paginatedtoOrgStore.get_user_orgs_paginated, which addsOrg.name == nameto the query before offset/limit.Issue Number
Linear: https://linear.app/all-hands-ai/issue/OHE-3156
How to Test
Automated (all run locally):
Manual, against a running deployment (with a session cookie or an API key):
GET /api/organizations?name=<exact name of an org you belong to>: expect 200 with that single org initemsandnext_page_id: null.acmeforAcme): expect 200 with an emptyitems.GET /api/organizations?name=<name of an existing org you are not a member of>: expect 200 with an emptyitems.GET /api/organizations?name=: expect 422.GET /api/organizationswithoutname: expect the same list as before this change.Video/Screenshots
N/A.
Type
Notes
org.namehas a unique constraint, so a name lookup returns at most one org. The existingOrgPageshape is kept so clients don't need a new response model.POST /api/organizationsdoes not add the creator as a member, so an account that creates orgs through that endpoint won't find them by name unless it is also a member. If BuildOne's provisioning account works that way, we'll need a follow-up lookup for super-role callers.Enterprise server image for this PR: