ForSURE.access_management.access_management_endpoint

GET /saas/access
async def get_access()

Retrieve list of users in the current organization.

This endpoint returns a list of all users in the current user's organization, excluding internal admin users and API tokens. Each user entry includes their ID, email, roles, and whether the current user can edit their roles.

Returns

list[dict]

List of user objects containing:

  • id str - User ID
  • you bool - True if this is the current user
  • roles list[str] - List of role names assigned to the user
  • email str - User email address
  • can_edit bool - Whether the current user can edit this user's roles

Example

curl -X GET "https://api.example.com/saas/access" \
-H "Authorization: Bearer YOUR_TOKEN"

Response Example

Successful response If the request was successful you should receive the status code 200 and a response body like this:

[
  {
    "id": "user-123",
    "you": true,
    "roles": ["USER_VIEW", "USER_EDIT"],
    "email": "user@example.com",
    "can_edit": true
  },
  {
    "id": "user-456",
    "you": false,
    "roles": ["USER_VIEW"],
    "email": "other@example.com",
    "can_edit": false
  }
]

Error response If the request failed you might receive status code 400, 401, 403, or 500 with a response body like this:

{
  "detail": "Failed to get access"
}

Note

Requires USER_VIEW permission. Internal admin users and API tokens are excluded from results.

GET /saas/access/roles
async def get_roles()

Retrieve all available roles grouped by category.

This endpoint returns all roles available in the system, grouped by role category. The roles are filtered based on the current user's access permissions.

Returns

dict

Dictionary of role categories, each containing:

  • description str - Description of the role category
  • roles list[dict] - List of roles in this category, each with:
    • name str - Role name
    • description str - Role description

Example

curl -X GET "https://api.example.com/saas/access/roles" \
-H "Authorization: Bearer YOUR_TOKEN"

Response Example

Successful response If the request was successful you should receive the status code 200 and a response body like this:

{
  "USER": {
    "description": "User management roles",
    "roles": [
      {
        "name": "USER_VIEW",
        "description": "View users"
      },
      {
        "name": "USER_EDIT",
        "description": "Edit user roles"
      }
    ]
  }
}

Error response If the request failed you might receive status code 400, 401, 403, or 500 with a response body like this:

{
  "detail": "Failed to get roles"
}

Note

Requires USER_EDIT permission. Only roles accessible by the current user are returned.

POST /saas/access/edit
async def edit_role()

Edit roles for a user in the organization.

This endpoint allows you to add or remove roles for a specific user. Roles are provided as comma-separated strings. You can only edit roles that you have access to.

Parameters

user_id_edited str - User ID of the user whose roles should be modified.

new_roles str, optional - Comma-separated list of role names to add.

removed_roles str, optional - Comma-separated list of role names to remove.

Returns

SuccessResponse

Response containing:

  • status str - "success" if operation completed
  • message str - "OK" if successful
  • data dict, optional - Additional response data

Example

curl -X POST "https://api.example.com/saas/access/edit" \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "user_id_edited=user-123" \
-F "new_roles=USER_VIEW,USER_EDIT" \
-F "removed_roles=USER_DELETE"

Response Example

Successful response If the request was successful you should receive the status code 200 and a response body like this:

{
  "status": "success",
  "message": "OK",
  "data": null
}

Error response If the request failed you might receive status code 400, 401, 403, or 500 with a response body like this:

{
  "detail": "Failed to edit roles"
}

Note

Requires USER_EDIT permission. You can only assign roles that you have access to.

POST /saas/access/add
async def add_user()

Add a user to the current organization.

This endpoint adds a user to the current organization's group. If the user does not exist in the system, they will be automatically provisioned in Keycloak and Shopify before being added to the organization. The user will have access to the organization but will need roles assigned separately.

Parameters

user_email str - Email address of the user to add to the organization.

Returns

SuccessResponse

Response containing:

  • status str - "success" if operation completed
  • message str - "OK" if successful
  • data dict, optional - Additional response data

Example

curl -X POST "https://api.example.com/saas/access/add" \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "user_email=user@example.com"

Response Example

Successful response If the request was successful you should receive the status code 200 and a response body like this:

{
  "status": "success",
  "message": "OK",
  "data": null
}

Error response If the request failed you might receive status code 400, 401, 403, or 500 with a response body like this:

{
  "detail": "Failed to add user"
}

Note

Requires USER_ADD permission. If the user does not exist in Keycloak, they will be automatically created. After adding a user, you may want to assign roles using the /edit endpoint. This endpoint is for adding users within the same organization; for inter-organization connections, use the /invite endpoint.

POST /saas/access/invite
async def invite_user()

Create an invitation for a user to join an organization.

This endpoint creates an invitation for a user to establish a connection between organizations. It verifies the user exists in Keycloak, stores the invitation, sends an email with an accept link, and creates a notification.

Parameters

user_email str - Email address of the user to invite.

company_name str - Company/organization name to match with the user's organizations.

relation_type str - Type of relationship (e.g., "agency", "customer").

Returns

SuccessResponse

Response containing:

  • status str - "success" if operation completed
  • message str - "OK" if successful
  • data dict, optional - Additional response data

Example

curl -X POST "https://api.example.com/saas/access/invite" \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "user_email=user@example.com" \
-F "company_name=Example Company" \
-F "relation_type=agency"

Response Example

Successful response If the request was successful you should receive the status code 200 and a response body like this:

{
  "status": "success",
  "message": "OK",
  "data": null
}

Error response If the request failed you might receive status code 400, 401, 403, or 500 with a response body like this:

{
  "detail": "Failed to invite user"
}

Note

Requires USER_ADD permission. The user must already exist and have organizations configured. The system matches the company_name to the user's organizations using fuzzy matching.

GET /saas/access/invite
async def list_invitations()

List all invitations related to the current organization.

This endpoint returns all invitations where the current organization is either the inviting party or the invited party. For pending invitations where the current user is the invitee, the accept token is included.

Returns

list[UserInvitationAPI]

List of invitation objects containing:

  • id int - Invitation ID
  • invited_email str - Email address of the invited user
  • company_name str - Customer company name
  • agency_name str - Agency organization name
  • relation_type str - Type of relationship
  • status str - Invitation status (PENDING, ACCEPTED, REJECTED)
  • created_at datetime - When the invitation was created
  • accepted_at datetime, optional - When the invitation was accepted
  • initiated_by str - Who initiated the invitation (CUSTOMER or AGENCY)
  • invited_by_username str - Username of the user who created the invitation
  • is_agency bool - Whether current user has agency access
  • can_edit bool - Whether current user can edit this invitation
  • is_inviting_organization bool - Whether current org is the initiator
  • accept_token str, optional - Token to accept invitation (only for pending invitations where user is invitee)
  • agency_roles list[str] - List of agency roles for this connection

Example

curl -X GET "https://api.example.com/saas/access/invite" \
-H "Authorization: Bearer YOUR_TOKEN"

Response Example

Successful response If the request was successful you should receive the status code 200 and a response body like this:

[
  {
    "id": 1,
    "invited_email": "user@example.com",
    "company_name": "Customer Corp",
    "agency_name": "Agency Inc",
    "relation_type": "agency",
    "status": "PENDING",
    "created_at": "2024-01-15T10:30:00Z",
    "accepted_at": null,
    "initiated_by": "CUSTOMER",
    "invited_by_username": "admin",
    "is_agency": false,
    "can_edit": true,
    "is_inviting_organization": true,
    "accept_token": null,
    "agency_roles": []
  }
]

Error response If the request failed you might receive status code 400, 401, 403, or 500 with a response body like this:

{
  "detail": "Failed to get invitations"
}

Note

Requires USER_VIEW permission. Accept tokens are only included for pending invitations where the current user is the invitee.

POST /saas/access/invite/accept
async def accept_invitation_endpoint()

Accept an invitation using the token received in the email.

This endpoint accepts a pending invitation and establishes the connection between organizations. It creates or updates client records, adds users to groups, and sends notifications. This endpoint does not require authentication; the token is sufficient.

Parameters

token str - Invitation token received in the email.

Returns

SuccessResponse

Response containing:

  • status str - "success" if operation completed
  • message str - "OK" if successful
  • data dict, optional - Additional response data

Example

curl -X POST "https://api.example.com/saas/access/invite/accept" \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "token=abc123def456"

Response Example

Successful response If the request was successful you should receive the status code 200 and a response body like this:

{
  "status": "success",
  "message": "OK",
  "data": null
}

Error response If the request failed you might receive status code 400, 401, 403, or 500 with a response body like this:

{
  "detail": "Failed to accept invitation"
}

Note

No authentication required - the token is sufficient. The invitation must be in PENDING status. Accepting an invitation creates client records and adds users to groups.

POST /saas/access/invite/123/reject
async def reject_invitation_endpoint()

Reject or decline an invitation.

This endpoint allows either party (inviting organization or invited organization) to reject an invitation. It removes the connection, updates client records, removes users from groups, and sends a notification to the other party.

Parameters

invitation_id int - ID of the invitation to reject.

Returns

SuccessResponse

Response containing:

  • status str - "success" if operation completed
  • message str - "OK" if successful
  • data dict, optional - Additional response data

Example

curl -X POST "https://api.example.com/saas/access/invite/123/reject" \
-H "Authorization: Bearer YOUR_TOKEN"

Response Example

Successful response If the request was successful you should receive the status code 200 and a response body like this:

{
  "status": "success",
  "message": "OK",
  "data": null
}

Error response If the request failed you might receive status code 400, 401, 403, or 500 with a response body like this:

{
  "detail": "Failed to reject invitation"
}

Note

Requires USER_VIEW permission. Can be called from either side of the invitation. Rejecting removes the connection and sends a notification to the other party.

POST /saas/access/invite/123/resend
async def resend_invitation()

Resend an existing invitation.

This endpoint resends an invitation email if the invitation is pending and was created more than 2 days ago. It verifies the user still exists, resends the email with the accept link, and creates a notification.

Parameters

invitation_id int - ID of the invitation to resend.

Returns

SuccessResponse

Response containing:

  • status str - "success" if operation completed
  • message str - "OK" if successful
  • data dict, optional - Additional response data

Example

curl -X POST "https://api.example.com/saas/access/invite/123/resend" \
-H "Authorization: Bearer YOUR_TOKEN"

Response Example

Successful response If the request was successful you should receive the status code 200 and a response body like this:

{
  "status": "success",
  "message": "OK",
  "data": null
}

Error response If the request failed you might receive status code 400, 401, 403, or 500 with a response body like this:

{
  "detail": "Failed to resend invitation"
}

Note

Requires USER_ADD permission. Only pending invitations older than 2 days can be resent. The invited user must still exist in Keycloak.

POST /saas/access/add-api-token
async def add_token()

Generate and add an API token to the current organization.

This endpoint creates a new API token for the current organization. The token can be used for programmatic API access without user authentication.

Returns

SuccessResponse

Response containing:

  • status str - "success" if operation completed
  • message str - "OK" if successful
  • data dict - Contains the generated token:
    • token str - The API token that can be used for authentication

Example

curl -X POST "https://api.example.com/saas/access/add-api-token" \
-H "Authorization: Bearer YOUR_TOKEN"

Response Example

Successful response If the request was successful you should receive the status code 200 and a response body like this:

{
  "status": "success",
  "message": "OK",
  "data": {
    "token": "api_token_abc123def456"
  }
}

Error response If the request failed you might receive status code 400, 401, 403, or 500 with a response body like this:

{
  "detail": "Failed to add API Token"
}

Note

Requires USER_ADD permission. Store the token securely as it cannot be retrieved again. The token is associated with the current organization.

POST /saas/access/delete
async def delete_user()

Remove a user from the current organization.

This endpoint removes a user from the current organization's group. The user is not deleted from the system, only removed from this organization.

Parameters

user_id_to_remove str - User ID of the user to remove from the organization.

Returns

SuccessResponse

Response containing:

  • status str - "success" if operation completed
  • message str - "OK" if successful
  • data dict, optional - Additional response data

Example

curl -X POST "https://api.example.com/saas/access/delete" \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "user_id_to_remove=user-123"

Response Example

Successful response If the request was successful you should receive the status code 200 and a response body like this:

{
  "status": "success",
  "message": "OK",
  "data": null
}

Error response If the request failed you might receive status code 400, 401, 403, or 500 with a response body like this:

{
  "detail": "Failed to delete user"
}

Note

Requires USER_DELETE permission. This only removes the user from the current organization, not from the entire system.

POST /saas/access/switch-company
async def switch_company()

Switch the current user's active organization/company.

This endpoint changes the user's current active organization context. The user must have access to the specified organization.

Parameters

company_name str - Name of the organization/company to switch to.

exact_match bool, default True - Whether to require an exact match for the company name.

Returns

SuccessResponse

Response containing:

  • status str - "success" if operation completed
  • message str - "OK" if successful
  • data dict, optional - Additional response data

Example

curl -X POST "https://api.example.com/saas/access/switch-company" \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "company_name=Example Company" \
-F "exact_match=true"

Response Example

Successful response If the request was successful you should receive the status code 200 and a response body like this:

{
  "status": "success",
  "message": "OK",
  "data": null
}

Error response If the request failed you might receive status code 400, 401, 403, or 500 with a response body like this:

{
  "detail": "Failed to switch companies"
}

Note

The user must have access to the specified organization. If exact_match is False, the system will attempt to find the closest matching organization name.

GET /saas/access/invite/123/agency-roles
async def get_agency_roles_endpoint()

Get agency roles for a specific connection.

This endpoint retrieves the list of agency roles assigned to a connection. Only accessible by the inviting organization (customer side).

Parameters

connection_id int - ID of the connection/invitation.

Returns

list[str]

List of agency role names assigned to this connection.

Example

curl -X GET "https://api.example.com/saas/access/invite/123/agency-roles" \
-H "Authorization: Bearer YOUR_TOKEN"

Response Example

Successful response If the request was successful you should receive the status code 200 and a response body like this:

[
  "ORDERS_VIEW",
  "ORDERS_EDIT",
  "REPORTS_VIEW"
]

Error response If the request failed you might receive status code 400, 401, 403, or 500 with a response body like this:

{
  "detail": "Failed to get agency roles"
}

Note

Requires USER_VIEW permission. Only accessible by the inviting organization (customer side).

POST /saas/access/invite/123/agency-roles/edit
async def edit_agency_roles_endpoint()

Edit agency roles for a connection.

This endpoint allows you to add or remove agency roles for a specific connection. Roles are provided as comma-separated strings. Similar to /edit for regular users, but specifically for agency connections. Only accessible by the inviting organization (customer side).

Parameters

connection_id int - ID of the connection/invitation.

new_roles str, optional - Comma-separated list of role names to add.

removed_roles str, optional - Comma-separated list of role names to remove.

Returns

SuccessResponse

Response containing:

  • status str - "success" if operation completed
  • message str - "OK" if successful
  • data dict, optional - Additional response data

Example

curl -X POST "https://api.example.com/saas/access/invite/123/agency-roles/edit" \
-H "Authorization: Bearer YOUR_TOKEN" \
-F "new_roles=ORDERS_VIEW,REPORTS_VIEW" \
-F "removed_roles=ORDERS_EDIT"

Response Example

Successful response If the request was successful you should receive the status code 200 and a response body like this:

{
  "status": "success",
  "message": "OK",
  "data": null
}

Error response If the request failed you might receive status code 400, 401, 403, or 500 with a response body like this:

{
  "detail": "Failed to edit agency roles"
}

Note

Requires USER_EDIT permission. Only accessible by the inviting organization (customer side). You can only assign roles that you have access to.