Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,16 +83,15 @@ users = norbix.membership.get_users()
print("Users response:", users)
```

### 3) Account-scoped Hub call (requires account_id)
### 3) Account Hub call (token only)

```python
from norbix_python import NorbixHub

norbix = NorbixHub(
api_key="sk_live_xxx",
project_id="proj_123",
account_id="acc_456", # required for account-scoped endpoints
)
) # no account_id: the gateway takes the account from the signed-in session

account = norbix.account.get_account_profile()
print(account)
Expand Down Expand Up @@ -202,7 +201,7 @@ Two related calls:
triggers that need a fix (for example, their provider is gone); `{"items": [...]}`.
- `norbix.hub.account.check_project_languages(project_id, languages=["en", "de"])` —
a dry run before `update_project_languages`: which templates miss a language;
`{"templates": [...]}`. Account scope.
`{"templates": [...]}`. Needs only a key or a token.

SMS campaigns can also go to the **account owner and team members**
(`deliveryType="AccountUsers"`, `accountUsers={"recipientsSourceType": "AccountUsers", "recipients": [...]}`);
Expand Down Expand Up @@ -340,15 +339,15 @@ Custom base URLs (`base_url_api=`, `base_url_hub=`, `NORBIX_API_URL`,
deployments are unaffected; the `nb-region` header is still sent when a
region is configured.

### Managing regions (Hub, account scope)
### Managing regions (Hub)

These endpoints require `account_id` (see
[Project vs account scope](#project-vs-account-scope)).
`regions.list()` needs no token at all; `update_project_regions` needs a key
or a bearer token (see [Project vs account scope](#project-vs-account-scope)).

```python
from norbix_python import NorbixHub

norbix = NorbixHub(api_key="sk_live_xxx", project_id="proj_123", account_id="acc_456")
norbix = NorbixHub(api_key="sk_live_xxx", project_id="proj_123")

# Regions available to the account.
# Response shape: {"items": [{"id": ..., "continent": ..., "name": ...}, ...]}
Expand Down Expand Up @@ -382,7 +381,6 @@ async def main() -> None:
async with AsyncNorbix(
api_key="sk_live_xxx",
project_id="proj_123",
account_id="acc_456",
region="nb-eu-germany",
) as client:
regions = await client.hub.regions.list()
Expand All @@ -397,8 +395,9 @@ async def main() -> None:
## Project vs account scope

- `project_id` is required (set explicitly or via env).
- `account_id` is optional
- Account-scoped Hub methods raise `NORBIX_ACCOUNT_SCOPE_REQUIRED` if `account_id` is not configured
- `account_id` is optional, and no Hub account method needs it: the gateway takes the account from the signed-in session or the project id in the path
- Account routes (profile, projects, project settings, team, licenses, …) need only a key or a bearer token
- Sign-up (`hub.account.create_account`), accepting an invitation (`hub.account.create_team_member_from_invitation`), the region list (`hub.account.get_account_regions`, `hub.regions.list`) and `hub.account.verify_account(accountId=..., token=...)` need no token at all — they are public on the gateway, and no `Authorization` header is sent
- Optional-scope methods (the signed notification preview links) send auth when the client has a token and never require one

## SDK maintenance
Expand Down
84 changes: 48 additions & 36 deletions docs/hub/account.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,59 @@

Access with `norbix.hub.account`.

Every method here needs only a key or a bearer token (scope `project`): the
gateway takes the account from the signed-in session, or from the project id
in the path, and never reads the `X-CM-AccountId` header. Four routes are
public on the gateway and need no token and no `account_id` at all (scope
`unauthenticated`, no `Authorization` header is sent): sign-up
(`create_account`), accepting an invitation
(`create_team_member_from_invitation`), the region list (`get_account_regions`,
also `norbix.hub.regions.list`) and `verify_account`, which takes the account
id once, in the request: `verify_account(accountId="acc_456", token="...")`.
Sync and async clients behave the same. Tests:
`tests/hub/test_account_token_only.py`.

| Method | Verb | Path | Scope |
| --- | --- | --- | --- |
| `get_account_profile` | `GET` | `/{version}/account/profile` | `account` |
| `update_account_profile` | `PUT` | `/{version}/account/profile` | `account` |
| `resend_account_verification_token` | `GET` | `/{version}/account/verify/resend` | `account` |
| `get_account_status` | `GET` | `/{version}/account/status` | `account` |
| `create_stripe_checkout_session` | `POST` | `/{version}/account/stripe/create-checkout-session` | `account` |
| `get_stripe_billing_portal_url` | `POST` | `/{version}/account/stripe/get-portal-url` | `account` |
| `create_team_member_from_invitation` | `POST` | `/{version}/account/team/member` | `account` |
| `verify_account` | `GET` | `/{version}/account/verify` | `account` |
| `delete_notifications_group` | `DELETE` | `/{version}/account/projects/{projectId}/notifications/settings/group` | `account` |
| `delete_notifications_tag` | `DELETE` | `/{version}/account/projects/{projectId}/notifications/settings/tag` | `account` |
| `remove_tag_from_notifications_group` | `DELETE` | `/{version}/account/projects/{projectId}/notifications/settings/group/tag` | `account` |
| `save_notifications_group` | `POST` | `/{version}/account/projects/{projectId}/notifications/settings/group` | `account` |
| `save_notifications_tag` | `POST` | `/{version}/account/projects/{projectId}/notifications/settings/tag` | `account` |
| `create_project` | `POST` | `/{version}/account/projects` | `account` |
| `delete_project` | `DELETE` | `/{version}/account/projects/{projectId}` | `account` |
| `get_project` | `GET` | `/{version}/account/projects/{projectId}` | `account` |
| `get_projects` | `GET` | `/{version}/account/projects` | `account` |
| `get_account_regions` | `GET` | `/{version}/account/regions` | `account` |
| `get_project_tokens` | `GET` | `/{version}/account/projects/{projectId}/tokens` | `account` |
| `update_project_accent_color` | `PATCH` | `/{version}/account/projects/{projectId}/settings/accent-color` | `account` |
| `update_project_icon` | `PATCH` | `/{version}/account/projects/{projectId}/settings/icon` | `account` |
| `update_project_logo` | `PATCH` | `/{version}/account/projects/{projectId}/settings/logo` | `account` |
| `update_project_main_color` | `PATCH` | `/{version}/account/projects/{projectId}/settings/main-color` | `account` |
| `update_project_allowed_origins` | `PATCH` | `/{version}/account/projects/{projectId}/settings/origins` | `account` |
| `update_project_default_language` | `PATCH` | `/{version}/account/projects/{projectId}/settings/default-language` | `account` |
| `update_project_description` | `PATCH` | `/{version}/account/projects/{projectId}/settings/description` | `account` |
| `disable_project` | `PATCH` | `/{version}/account/projects/{projectId}/disable` | `account` |
| `enable_project` | `PATCH` | `/{version}/account/projects/{projectId}/enable` | `account` |
| `check_project_languages` | `POST` | `/{version}/account/projects/{projectId}/settings/languages/check` | `account` |
| `update_project_languages` | `PATCH` | `/{version}/account/projects/{projectId}/settings/languages` | `account` |
| `update_project_url` | `PATCH` | `/{version}/account/projects/{projectId}/settings/url` | `account` |
| `update_project_name` | `PATCH` | `/{version}/account/projects/{projectId}/settings/name` | `account` |
| `update_project_regions` | `PATCH` | `/{version}/account/projects/{projectId}/settings/regions` | `account` |
| `create_account` | `POST` | `/{version}/account` | `account` |
| `get_account_profile` | `GET` | `/{version}/account/profile` | `project` |
| `update_account_profile` | `PUT` | `/{version}/account/profile` | `project` |
| `resend_account_verification_token` | `GET` | `/{version}/account/verify/resend` | `project` |
| `get_account_status` | `GET` | `/{version}/account/status` | `project` |
| `create_stripe_checkout_session` | `POST` | `/{version}/account/stripe/create-checkout-session` | `project` |
| `get_stripe_billing_portal_url` | `POST` | `/{version}/account/stripe/get-portal-url` | `project` |
| `create_team_member_from_invitation` | `POST` | `/{version}/account/team/member` | `unauthenticated` |
| `verify_account` | `GET` | `/{version}/account/verify` | `unauthenticated` |
| `delete_notifications_group` | `DELETE` | `/{version}/account/projects/{projectId}/notifications/settings/group` | `project` |
| `delete_notifications_tag` | `DELETE` | `/{version}/account/projects/{projectId}/notifications/settings/tag` | `project` |
| `remove_tag_from_notifications_group` | `DELETE` | `/{version}/account/projects/{projectId}/notifications/settings/group/tag` | `project` |
| `save_notifications_group` | `POST` | `/{version}/account/projects/{projectId}/notifications/settings/group` | `project` |
| `save_notifications_tag` | `POST` | `/{version}/account/projects/{projectId}/notifications/settings/tag` | `project` |
| `create_project` | `POST` | `/{version}/account/projects` | `project` |
| `delete_project` | `DELETE` | `/{version}/account/projects/{projectId}` | `project` |
| `get_project` | `GET` | `/{version}/account/projects/{projectId}` | `project` |
| `get_projects` | `GET` | `/{version}/account/projects` | `project` |
| `get_account_regions` | `GET` | `/{version}/account/regions` | `unauthenticated` |
| `get_project_tokens` | `GET` | `/{version}/account/projects/{projectId}/tokens` | `project` |
| `update_project_accent_color` | `PATCH` | `/{version}/account/projects/{projectId}/settings/accent-color` | `project` |
| `update_project_icon` | `PATCH` | `/{version}/account/projects/{projectId}/settings/icon` | `project` |
| `update_project_logo` | `PATCH` | `/{version}/account/projects/{projectId}/settings/logo` | `project` |
| `update_project_main_color` | `PATCH` | `/{version}/account/projects/{projectId}/settings/main-color` | `project` |
| `update_project_allowed_origins` | `PATCH` | `/{version}/account/projects/{projectId}/settings/origins` | `project` |
| `update_project_default_language` | `PATCH` | `/{version}/account/projects/{projectId}/settings/default-language` | `project` |
| `update_project_description` | `PATCH` | `/{version}/account/projects/{projectId}/settings/description` | `project` |
| `disable_project` | `PATCH` | `/{version}/account/projects/{projectId}/disable` | `project` |
| `enable_project` | `PATCH` | `/{version}/account/projects/{projectId}/enable` | `project` |
| `check_project_languages` | `POST` | `/{version}/account/projects/{projectId}/settings/languages/check` | `project` |
| `update_project_languages` | `PATCH` | `/{version}/account/projects/{projectId}/settings/languages` | `project` |
| `update_project_url` | `PATCH` | `/{version}/account/projects/{projectId}/settings/url` | `project` |
| `update_project_name` | `PATCH` | `/{version}/account/projects/{projectId}/settings/name` | `project` |
| `update_project_regions` | `PATCH` | `/{version}/account/projects/{projectId}/settings/regions` | `project` |
| `create_account` | `POST` | `/{version}/account` | `unauthenticated` |
| `get_account_collaborators` | `GET` | `/{version}/account/collaborators` | `project` |
| `get_my_account_user_profile` | `GET` | `/{version}/account/me` | `project` |
| `update_my_account_user_phone` | `PUT` | `/{version}/account/me/phone` | `project` |
| `send_invite_to_team_member` | `POST` | `/{version}/account/team/member/invite` | `account` |
| `get_licenses` | `GET` | `/{version}/account/licenses` | `account` |
| `send_invite_to_team_member` | `POST` | `/{version}/account/team/member/invite` | `project` |
| `get_licenses` | `GET` | `/{version}/account/licenses` | `project` |
| `get_project_ai_settings` | `GET` | `/{version}/account/projects/{projectId}/ai/settings` | `project` |
| `update_project_ai_settings` | `PUT` | `/{version}/account/projects/{projectId}/ai/settings` | `project` |
| `create_project_ai_assistant` | `POST` | `/{version}/account/projects/{projectId}/ai/assistants` | `project` |
Expand Down
Loading
Loading