def grant(
slug: str,
member_id: str,
*,
timeout: float | None = None,
) -> GrantedProductAccessResourceasync def grant(
slug: str,
member_id: str,
*,
timeout: float | None = None,
) -> GrantedProductAccessResourceGrants one workspace member access to a product. The two path values are the whole input, there is no request body, and the call is idempotent: re-granting an existing grant succeeds and still returns 'granted': True.
member_id is a workspace member id, the value on access.list entries and on the members list, not a user id. Passing a user id reports a missing member, which is the most common failure here. Granting on a public product is allowed and only records the row, which starts affecting reads if the product is later made private.
Example
from envless import envless
granted = envless.products.access.grant(
'billing', '8f1c0e42-9b7a-4d21-9d0e-3a41c7f5b210'
)
user = granted['user']
print(granted['granted'], user['email'] if user else None)import asyncio
from envless import AsyncEnvless
async def main() -> None:
async with AsyncEnvless() as envless:
granted = await envless.products.access.grant(
'billing', '8f1c0e42-9b7a-4d21-9d0e-3a41c7f5b210'
)
user = granted['user']
print(granted['granted'], user['email'] if user else None)
asyncio.run(main())Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
slug | str | Yes | Product slug, or the product uniqueId when the value is UUID shaped. |
member_id | str | Yes | Workspace member id, the same id space the members endpoints use. |
timeout | float | No | Seconds each attempt of this call may take, the response body included, before it raises EnvlessNetworkError with is_timeout set. Overrides the client's timeout for this call, and 0 turns the limit off. |
Returns
GrantedProductAccessResource with the member id, a user summary and granted.
Worth knowing
- The row is upserted, so the API answers 200 rather than 201 even on a first grant.
- A product beyond the plan allowance refuses grants with the same locked error that blocks updates.
Required scopes
product-access:write
Underlying endpoint
PUT /products/{slug}/access/{memberId}
Request and response schema, every error code, and a live playground.
In TypeScript
envless.products.access.grant()
The same method in @goenvless/sdk, with the same request, retries and errors.