Skip to main content

Using the PointFive API

Updated over a month ago

The PointFive platform provides a comprehensive GraphQL API for managing teams and users in your organization. These APIs enable you to programmatically create organizational structures, manage team memberships, control resource access, and handle user lifecycle operations.

All available updates (Mutations), including those outlined here, can be fully explored in the API Playground. Note that you need to be logged in to be able to access it.

This tool allows you to browse the schema, test queries, and see all supported operations directly from your browser.

Opportunities API

List Opportunities

Retrieve opportunities with filtering, sorting, and pagination.

query ListOpportunities {
opportunities(
where: {
status: { IN: [OPEN, IN_PROGRESS] }
savingAmount: { GTE: 100 }
definitionCategory: { IN: [unused_resource, underutilization] }
}
limit: 20
offset: 0
orderBy: [{ savingAmount: DESC }]
) {
id
name
savingAmount
currentCost
priority
risk
effort
status
resource {
name
provider
service
region
}
}
}

Common Filters:

  • status - Filter by OPEN, IN_PROGRESS, VALIDATED, RESOLVED, or DISMISSED

  • savingAmount - Filter by potential savings (supports GTE, LTE, GT, LT, EQ)

  • definitionCategory - Filter by opportunity type

  • risk - Filter by risk level (1-5)

  • effort - Filter by implementation effort (1-5)

  • assignedUser - Filter by assigned user

  • projectId - Filter by specific project

    Use Cases:

  • Find high-value opportunities above a savings threshold

  • List opportunities for specific cloud services

  • Get opportunities assigned to your team

  • Filter by risk/effort for prioritization

Get Single Opportunity

Retrieve detailed information about a specific opportunity.

Required Role: ADMIN or MEMBER

query GetOpportunity {
opportunity(id: "opportunity-uuid") {
id
name
diagnosis {
description
descriptionText
data
}
recommendation {
summary
summaryText
}
savingAmount
currentCost
priority
risk
effort
status
resource {
id
name
provider
service
region
tags
}
remediationLinks {
name
url
}
platformUrl
}
}


Data Export API

The PointFive platform provides asynchronous export capabilities for opportunities and resources data. Exports are generated in the background and can be downloaded once ready. This API uses a poll-based pattern where you initiate an export, receive an export asset ID, and poll until the export is complete.

What can be exported:

  • Opportunities: Cost-saving recommendations and optimization findings identified by PointFive

  • Resources: Cloud infrastructure resources (EC2 instances, S3 buckets, RDS databases, etc.) with cost and savings data.

Available export formats:

  • CSV - Comma-separated values

  • JSON - JavaScript Object Notation

How It Works

  1. Generate Export: Call a mutation to create an export with your desired filters and columns

  2. Receive Export Asset ID: The mutation returns immediately with an ExportAsset containing a unique ID

  3. Poll for Status: Query the exportAsset endpoint using the ID to check progress

  4. Download: Once status = COMPLETED, use the temporary URL to download your file

Mutations

Export Opportunities GraphQL Schema

mutation {generateOpportunitiesExportAsset( 
selectedColumns: [String!]
filter: OpportunitiesFilterInput
exportType: ExportType! ): ExportAsset!
}

Export Resources GraphQL Schema

mutation {generateResourcesExportAsset( 
selectedColumns: [String!]
filter: ResourceFilterInput
orderBy: [ResourceOrdering!]
exportType: ExportType! ): ExportAsset!
}

Query

graphql

type Query {   
""" Get an export asset by ID. Returns null if not found or expired. Client should poll this endpoint until status is COMPLETED or FAILED. """
exportAsset(id: UUID!): ExportAsset }

Types

graphql

enum ExportType {   
CSV
JSON
}

enum ExportAssetStatus {
PENDING # Export request received, not yet processing
PROCESSING # Export is being generated
COMPLETED # Export is ready for download
FAILED # Export failed (check logs or retry)
}

type ExportAsset {
id: UUID!
exportFormat: ExportType!
status: ExportAssetStatus!
url: String # Download URL (only available when status = COMPLETED)
createdAt: Time!
expiresAt: Time!
}


Opportunities Export

generateOpportunitiesExportAsset

Generate an export of cost optimization opportunities identified by PointFive.

Parameters

Parameter

Type

Required

Description

selectedColumns

[String!]

No

List of column names to include in the export. If omitted, all available columns are included.

filter

OpportunitiesFilterInput

No

Filter criteria to narrow down which opportunities to export

exportType

ExportType!

Yes

Export format: CSV or JSON

Available Columns

Example columns you can include in selectedColumns:

  • id - Opportunity ID

  • name - Opportunity type/name

  • projectId - Project/account ID where the opportunity exists

  • resourceId - Associated resource ID

  • status - Opportunity status (e.g., open, dismissed, resolved)

  • risk - Risk score associated with the opportunity

  • effort - Estimated effort to implement

  • priority - Priority level

  • savingAmount - Potential monthly savings amount

  • currentCost - Current monthly cost of the resource

  • definitionId - Opportunity definition/template ID

  • createdAt - When the opportunity was created

  • updatedAt - When the opportunity was last updated

Example Usage

Export all high-priority opportunities created in the last 30 days:

graphql

mutation {
generateOpportunitiesExportAsset(
selectedColumns: [
"id",
"name",
"projectId",
"resourceId",
"savingAmount",
"currentCost",
"priority",
"status",
"createdAt"
]
filter: {
priority: { gte: 7.0 }
createdAtRelative: { unit: DAYS, value: 30, direction: PAST }
}
exportType: CSV
) {
id
status
exportFormat
createdAt
expiresAt
}
}

Resources Export

generateResourcesExportAsset

Generate an export of cloud infrastructure resources tracked by PointFive.

Parameters

Parameter

Type

Required

Description

selectedColumns

[String!]

No

List of column names to include in the export. If omitted, all available columns are included.

filter

ResourceFilterInput

No

Filter criteria to narrow down which resources to export

orderBy

[ResourceOrdering!]

No

Sort order for the exported data

exportType

ExportType!

Yes

Export format: CSV or JSON

Available Columns

Example columns you can include in selectedColumns:

  • id - Unique resource ID

  • resourceId - Provider-specific resource identifier (e.g., ARN)

  • name - Resource name

  • typeName - Canonical resource type (e.g., AWS::EC2::Instance)

  • resourceType - Resource type classification

  • service - Cloud service (e.g., EC2, RDS, S3)

  • provider - Cloud provider (AWS, Azure, GCP)

  • projectId - Project/account ID

  • region - Geographic region

  • creationTime - When the resource was created

  • deletionTime - When the resource was deleted (if applicable)

  • cost - Current monthly cost

  • monthlySavings - Potential monthly savings

  • monthlyCumulativeCloudSavings - Cumulative cloud savings per month

  • monthlyCumulativeApplicativeSavings - Cumulative application-level savings per month

Note: If selectedColumns is omitted or empty, all available columns will be included in the export.

Ordering Options

The ResourceOrdering allows you to sort the exported data:

Available sort fields:

  • name - Sort by resource name

  • resourceType - Sort by resource type

  • creationTime - Sort by creation date

  • deletionTime - Sort by deletion date

  • cost - Sort by current cost

  • service - Sort by service

  • provider - Sort by provider

  • potentialSavings - Sort by potential savings

Each field accepts an OrderDirection:

  • ASC - Ascending order

  • DESC - Descending order

Response

Returns an ExportAsset object with:

  • id: UUID to use for polling

  • status: Initially PENDING

  • exportFormat: The format you requested

  • createdAt: Timestamp of creation

  • expiresAt: When the export asset expires

Example Usage

Export all EC2 instances with potential savings, sorted by savings:

graphql

mutation {
generateResourcesExportAsset(
selectedColumns: [
"id",
"name",
"resourceId",
"service",
"region",
"cost",
"monthlySavings",
"projectId"
]
filter: {
service: { eq: "EC2" }
monthlySavings: { gt: 0 }
}
orderBy: [
{ monthlySavings: DESC }
]
exportType: CSV
) {
id
status
exportFormat
createdAt
expiresAt
}
}

Downloading Your Export

Once the export status is COMPLETED, the url field will contain a temporary download link.

{
"data": {
"exportAsset": {
"id": "d7d59999-642a-400e-b85c-700ed0ee5363",
"status": "COMPLETED",
"url": "your download url",
"exportFormat": "CSV",
"createdAt": "2026-01-06T12:49:40.755168Z",
"expiresAt": "2026-01-13T12:49:40.753742Z"
}
}
}

Copy the URL into your browser and the file will be downloaded instantly.


Teams API

Teams organize users into groups for access control and resource management. Teams can have hierarchical structures and resource allocation rules.

Batch Import Teams

The batchImportTeams mutation allows you to create or update single or multiple teams in a single atomic operation. You can define team hierarchies, assign members, and configure resource allocation rules for each team.


GraphQL Schema

mutation BatchImportTeams($input: BatchImportTeamsInput!) {
batchImportTeams(input: $input) {
success
importedTeamIds
}
}

Important Behaviors

Upsert Mode (Default: removeExistingStructure: false)

  • Creates new teams that don't exist

  • Updates existing teams by:

    • Adding new members to existing member lists (doesn't remove existing members)

    • Adding new resource allocation rules

    • Replacing rules that have matching names with new definitions

  • Preserves teams not included in the import

  • Preserves existing members not in the import

Full Replacement Mode (removeExistingStructure: true)

  • Deletes all existing non-organization teams before import

  • Creates only the teams specified in the input

  • Use with caution - this is a destructive operation

Input Parameters

BatchImportTeamsInput

Field

Type

Required

Description

removeExistingStructure

Boolean

No

If true, deletes all existing non-organization teams before importing. If false (default), performs upsert: creates new teams and updates existing ones additively.

teams

[ImportTeamInput!]!

Yes

List of teams to import. Each team will be created or updated atomically.

ImportTeamInput

Field

Type

Required

Description

name

String!

Yes

Name of the team

parentName

String

No

Name of the parent team (for creating hierarchies)

members

[UUID!]

No

Array of user IDs to assign as team members

resourceAllocationRules

[ResourceAllocationRuleInput!]

No

Rules defining which cloud resources belong to this team

ResourceAllocationRuleInput

Field

Type

Required

Description

name

String!

Yes

Name of the allocation rule

rule

ResourceAllocationRuleFilter!

Yes

Filter criteria for matching resources

Response

BatchImportTeamsPayload

Field

Type

Description

success

Boolean!

Whether the operation completed successfully

importedTeamIds

[UUID!]!

Array of team IDs that were created or updated

Resource Allocation Rule Filters

Resource allocation rules determine which cloud resources are assigned to each team. You can filter by various resource attributes and combine filters using logical operators.

Available Filter Types

1. String Filters

Used for: resourceId, region, service, managementAccountId

Operators:

  • IN: Matches any value in the array

  • NIN: Does not match any value in the array

  • ILIKE: Case-insensitive pattern matching (supports % wildcard)

  • NILIKE: Negated case-insensitive pattern matching

Example:

graphql

service: { IN: ["EC2", "RDS", "S3"] }
region: { ILIKE: "us-%" } # Matches us-east-1, us-west-2, etc.

2. String Map Filters

Used for: tag, groupTag, projectTag

Operators:

  • IN: Matches tags where key-value pairs are in the array

  • NIN: Does not match tags in the array

  • HasKey: Resource has a tag with this key (any value)

  • NHasKey: Resource does not have a tag with this key

  • Empty: Resource has a tag with this key but empty value

  • NEmpty: Resource has a tag with this key and non-empty value

  • ILIKE: Case-insensitive pattern matching on key-value pairs

Example:

graphql

tag: {
IN: [
{ key: "Environment", value: "Production" },
{ key: "Environment", value: "Staging" }
]
}
tag: { HasKey: "Team" } # Any resource with a "Team" tag

3. Resource Group Filter

Used for: resourceGroup

Operators:

  • IN: Matches resources in specified resource groups (by name and subscription ID)

  • NIN: Does not match resources in specified resource groups

Example:

graphql

resourceGroup: {
IN: [
{ name: "production-rg", subscriptionId: "abc123" }
]
}

4. Project Filter

Used for: project

Operators:

  • id: Match by project ID

  • name: Match by project name

  • canonicalName: Match by canonical name

  • managementAccountId: Match by management account ID

  • AND: Combine multiple project filters with AND logic

  • OR: Combine multiple project filters with OR logic

Example:

graphql

project: {
name: { ILIKE: "prod-%" }
managementAccountId: { IN: ["123456789012"] }
}

5. Logical Operators

Combine multiple filters with AND / OR logic

Example:

graphql

AND: [
{ service: { IN: ["EC2"] } },
{ region: { IN: ["us-east-1"] } },
{ tag: { HasKey: "CostCenter" } }
]

Usage Examples

Example 1: Simple Team Import with Members

Create two teams with assigned members but no resource allocation rules.

graphql

mutation {
batchImportTeams(input: {
teams: [
{
name: "Engineering"
members: [
"550e8400-e29b-41d4-a716-446655440001",
"550e8400-e29b-41d4-a716-446655440002"
]
},
{
name: "Marketing"
members: [
"550e8400-e29b-41d4-a716-446655440003"
]
}
]
}) {
success
importedTeamIds
}
}

Example 2: Team Hierarchy with Resource Rules

Create a parent team "Engineering" with two child teams, each with their own resource allocation rules.

graphql

mutation {
batchImportTeams(input: {
teams: [
{
name: "Engineering"
resourceAllocationRules: [
{
name: "All Engineering Resources"
rule: {
tag: {
IN: [
{ key: "Department", value: "Engineering" }
]
}
}
}
]
},
{
name: "Backend Team"
parentName: "Engineering"
members: [
"550e8400-e29b-41d4-a716-446655440001",
"550e8400-e29b-41d4-a716-446655440002"
]
resourceAllocationRules: [
{
name: "Backend Production Services"
rule: {
AND: [
{
service: { IN: ["EC2", "RDS", "ElastiCache"] }
},
{
tag: {
IN: [
{ key: "Environment", value: "Production" },
{ key: "Team", value: "Backend" }
]
}
}
]
}
}
]
},
{
name: "Frontend Team"
parentName: "Engineering"
members: [
"550e8400-e29b-41d4-a716-446655440003"
]
resourceAllocationRules: [
{
name: "Frontend Resources"
rule: {
AND: [
{
service: { IN: ["S3", "CloudFront", "Lambda"] }
},
{
tag: {
HasKey: "Frontend"
}
}
]
}
}
]
}
]
}) {
success
importedTeamIds
}
}

Example 3: Regional Team Allocation

Create teams based on geographic regions with region-specific resource allocation.

graphql

mutation {
batchImportTeams(input: {
teams: [
{
name: "US Operations"
resourceAllocationRules: [
{
name: "US Regions"
rule: {
region: {
ILIKE: "us-%"
}
}
}
]
},
{
name: "EU Operations"
resourceAllocationRules: [
{
name: "EU Regions"
rule: {
region: {
ILIKE: "eu-%"
}
}
}
]
},
{
name: "APAC Operations"
resourceAllocationRules: [
{
name: "APAC Regions"
rule: {
region: {
IN: ["ap-southeast-1", "ap-northeast-1", "ap-south-1"]
}
}
}
]
}
]
}) {
success
importedTeamIds
}
}

Example 4: Multi-Account Structure

Create teams mapped to different AWS management accounts with specific resource patterns.

graphql

mutation {
batchImportTeams(input: {
teams: [
{
name: "Production Account Team"
resourceAllocationRules: [
{
name: "Production Account Resources"
rule: {
AND: [
{
managementAccountId: { IN: ["123456789012"] }
},
{
tag: {
IN: [
{ key: "Environment", value: "Production" }
]
}
}
]
}
}
]
},
{
name: "Development Account Team"
resourceAllocationRules: [
{
name: "Dev Account Resources"
rule: {
managementAccountId: { IN: ["987654321098"] }
}
}
]
}
]
}) {
success
importedTeamIds
}
}

Example 5: Complex Filter with Specific Resource IDs

Create a team responsible for specific critical infrastructure resources.

graphql

mutation {
batchImportTeams(input: {
teams: [
{
name: "Database Team"
members: [
"550e8400-e29b-41d4-a716-446655440010"
]
resourceAllocationRules: [
{
name: "Critical Databases"
rule: {
OR: [
{
resourceId: {
IN: [
"arn:aws:elasticache:us-east-1:587752543875:replicationgroup:pointfive-graphql",
"arn:aws:rds:us-east-1:587752543875:db:production-primary"
]
}
},
{
AND: [
{
service: { IN: ["RDS", "ElastiCache", "DynamoDB"] }
},
{
tag: {
IN: [
{ key: "Tier", value: "Critical" }
]
}
}
]
}
]
}
}
]
}
]
}) {
success
importedTeamIds
}
}

Example 6: Full Replacement Mode

Replace the entire team structure with a new organization.

graphql

mutation {
batchImportTeams(input: {
removeExistingStructure: true
teams: [
{
name: "Executive"
members: ["550e8400-e29b-41d4-a716-446655440001"]
},
{
name: "Engineering"
parentName: "Executive"
resourceAllocationRules: [
{
name: "Engineering Tagged Resources"
rule: {
tag: {
HasKey: "Engineering"
}
}
}
]
},
{
name: "Sales"
parentName: "Executive"
resourceAllocationRules: [
{
name: "Sales Tagged Resources"
rule: {
tag: {
HasKey: "Sales"
}
}
}
]
}
]
}) {
success
importedTeamIds
}
}Example 7: Azure Resource Groups

Create teams based on Azure resource groups.

graphql

mutation {
batchImportTeams(input: {
teams: [
{
name: "Production Infrastructure"
resourceAllocationRules: [
{
name: "Production Resource Groups"
rule: {
resourceGroup: {
IN: [
{
name: "production-rg"
subscriptionId: "abc123-def456-ghi789"
},
{
name: "prod-networking-rg"
subscriptionId: "abc123-def456-ghi789"
}
]
}
}
}
]
}
]
}) {
success
importedTeamIds
}
}

Best Practices

  1. Test with upsert mode first: Start without removeExistingStructure: true to safely test your team structure

  2. Order teams hierarchically: List parent teams before child teams in your array

  3. Use descriptive rule names: Rule names help identify what resources each rule captures

  4. Combine filters strategically: Use AND/OR operators to create precise resource matching logic

  5. Leverage tag-based allocation: Tags provide the most flexible resource allocation strategy

  6. Document your structure: Keep external documentation of your team hierarchy and allocation logic

Get Team

Retrieve detailed information about a specific team.

Required Role: ADMIN

query GetTeam {
getTeam(id: "team-uuid-here") {
id
name
type
members {
userId
user {
firstName
lastName
email
}
}
memberCount
childTeams {
id
name
}
parentTeams {
id
name
}
resourceAllocationRules {
name
rule
}
createdAt
updatedAt
}
}

Parameters:

  • id (UUID) - Team ID

  • name (String) - Team name (provide either id or name)

List Teams

Retrieve all teams with optional filtering.

Required Role: ADMIN or MEMBER

query ListTeams {
listTeams(
where: { name: { contains: "Engineering" }, type: TEAM, orphan: false }
limit: 50
offset: 0
) {
id
name
type
memberCount
resourceAllocationRulesCount
createdAt
}
}

Filters:

  • name - Filter by team name (supports contains, equals, etc.)

  • type - Filter by ORGANIZATION or TEAM

  • orphan - If true, only return teams with no parent

Create Team

Create a new team.

Required Role: ADMIN

mutation CreateTeam {
createTeam(input: { name: "Platform Engineering", members: ["user-uuid-1", "user-uuid-2"] }) {
id
name
type
members {
userId
user {
firstName
lastName
}
}
createdAt
}
}

Input:

  • name (required) - Team name (1-80 characters, must be unique)

  • members (optional) - List of user IDs to add as initial members

Update Team

Update an existing team's information.

Required Role: ADMIN

graphql

mutation UpdateTeam {
updateTeam(
id: "team-uuid-here"
input: {
name: "Updated Team Name"
ResourceAllocationRules: [
{
name: "Production Resources"
rule: { AND: [{ tag: { IN: { Key: "Environment", Values: ["production"] } } }] }
}
]
}
) {
success
team {
id
name
resourceAllocationRules {
name
rule
}
}
}
}

Add Members to Team

Add users to a team.

Required Role: ADMIN

mutation AddMembers {
addMembersToTeam(id: "team-uuid-here", userIds: ["user-uuid-1", "user-uuid-2"]) {
success
}
}

Remove Member from Teams

Remove a user from multiple teams.

Required Role: ADMIN

mutation RemoveFromTeams {
removeMemberFromTeams(userId: "user-uuid-here", teamIds: ["team-uuid-1", "team-uuid-2"]) {
success
}
}

Manage Team Hierarchy

Add or remove child teams to create organizational structures.

Required Role: ADMIN

# Add child teams
mutation AddChildTeams {
addChildTeamsToTeam(
id: "parent-team-uuid"
childTeamIds: ["child-team-uuid-1", "child-team-uuid-2"]
) {
success
}
}

# Remove child teams
mutation RemoveChildTeams {
removeChildTeamsFromTeam(
id: "parent-team-uuid", childTeamIds: ["child-team-uuid-1"]) {
success
}
}

Delete Team

Permanently delete a team.

Required Role: ADMIN

mutation DeleteTeam {
deleteTeam(
id: "team-uuid"
deleteSubTeams: false
) {
deleteCount
}
}

Parameters:

  • id (required) - Team ID to delete

  • deleteSubTeams (required) - If true, recursively deletes all child teams

Warning: This operation cannot be undone. All team members will be unassigned from the team, and resource allocation rules will be deleted.

Resource Allocation Rules

Resource Allocation Rules (RARs) determine which cloud resources a team can access.Rules are composed of filters that can be combined to create precise resource matching criteria.

Understanding AND vs OR Logic

Within a Single Rule - AND Logic (Implicit)

When you specify multiple filter criteria within the same rule object, they are combined with AND logic. This means a resource must match ALL criteria to be included.

Example: Tag-Based Allocation

{
name: "Production Environment"
rule: {
AND: [
{ tag: { IN: { Key: "Environment", Values: ["production"] } } }
{ tag: { IN: { Key: "Team", Values: ["platform"] } } }
]
}
}

Example: Multi-Region Allocation

{
name: "US Regions"
rule: {
AND: [{ region: { IN: ["us-east-1", "us-west-2"] } }]
}
}

Across Multiple Rules - OR Logic

When you create multiple Resource Allocation Rules for a team, they work with OR logic. A resource only needs to match ANY ONE of the rules to be accessible to the team.

Example: Resources matching ANY rule are included

{
name: "Development or Staging"
rule: {
AND: [
{
OR: [
{ tag: { IN: { Key: "Environment", Values: ["development"] } } }
{ tag: { IN: { Key: "Environment", Values: ["staging"] } } }
]
}
]
}
}

Available Filters:

  • accounts - Filter by cloud account IDs

  • regions - Filter by cloud regions

  • services - Filter by cloud services

  • projects - Filter by project IDs

  • tags - Filter by resource tags (key-value pairs)

  • providers - Filter by cloud provider

  • resourceGroups - Filter by Azure resource groups

  • OR - Combine multiple filters with OR logic


Resource allocation rules filters explained

Resource allocation rules determine which cloud resources are automatically assigned to each team. These rules use filters to match resources based on their attributes like tags, regions, services, and more.

Filter Criteria Overview

Filter Field

Description

Cloud Providers

Filter Type

resourceId

Match by specific resource ARN or identifier

AWS, Azure, GCP

String Filter

region

Match by cloud region/location

AWS, Azure, GCP

String Filter

service

Match by cloud service type

AWS, Azure, GCP

String Filter

managementAccountId

Match by root/management account

AWS, Azure, GCP

String Filter

tag

Match by resource tags (key-value pairs)

AWS, Azure, GCP

String Map Filter

groupTag

Match by resource group tags

Azure

String Map Filter

projectTag

Match by project tags

GCP

String Map Filter

resourceGroup

Match by Azure resource group

Azure

Resource Group Filter

project

Match by GCP/Azure project and AWS accounts

GCP

Project Filter


Users API

Manage users in your organization, including their roles, team memberships, and permissions.

List Users

Retrieve all users with filtering and sorting.

Required Role: ADMIN or MEMBER

query ListUsers {
users(
search: "john"
where: { role: { in: [ADMIN] }, email: { contains: "@example.com" } }
order: [{ lastName: ASC }, { firstName: ASC }]
offset: 0
limit: 50
) {
id
email
firstName
lastName
fullName
role
teams {
id
name
}
lastLoginAt
createdAt
}
}

Parameters:

  • search - Search by email or name

  • where - Filter criteria (email, firstName, lastName, role)

  • order - Sort order (by email, firstName, lastName, or role)

  • offset - Results to skip (for pagination)

  • limit - Maximum results to return

Create User

Create new users in your organization.

Required Role: ADMIN

mutation CreateUsers {
createUser(
input: [
{
email: "[email protected]"
firstName: "John"
lastName: "Doe"
role: MEMBER
teams: [{ id: "team-uuid-here" }]
remoteAssistanceConsent: true
silentMode: false
}
]
) {
success
users {
id
email
firstName
lastName
fullName
role
teams {
id
name
}
}
}
}

Input:

  • email (required) - User's email address (must be unique)

  • firstName (required) - First name (1-256 characters)

  • lastName (required) - Last name (1-256 characters)

  • role (required) - User role (ADMIN or MEMBER)

  • teams (optional) - Teams to assign user to

  • remoteAssistanceConsent (required) - Remote assistance consent

  • silentMode (optional) - If true, skip sending invitation email

Update User

Update an existing user's information.

Required Role: ADMIN

mutation UpdateUser {
updateUser(
userId: "user-uuid-here"
input: { firstName: "Jane", lastName: "Smith", role: ADMIN, remoteAssistanceConsent: true }
) {
success
user {
id
firstName
lastName
role
}
}
}

Note: Email addresses cannot be changed through this mutation.

Delete User

Permanently remove a user from the organization.

Required Role: ADMIN

mutation DeleteUser {
deleteUser(userId: "user-uuid-here") {
success
user {
id
email
firstName
lastName
}
}
}

Restrictions:

  • Cannot delete yourself

  • Cannot delete the last admin in the organization

Effects:

  • User is permanently removed

  • User is removed from all teams

  • API keys are revoked

  • Activity history is preserved for audit


Advanced Topics

Pagination

Most list queries support offset/limit pagination:

# First page
query FirstPage {
opportunities(limit: 20, offset: 0) {
id
name
}
}

# Second page
query SecondPage {
opportunities(limit: 20, offset: 20) {
id
name
}
}

Best Practice: Use a page size of 20-100 for optimal performance.

Filtering

The API supports powerful filtering capabilities:

String Filters:

name: {
EQ: "Exact match"
LIKE: "Contains (case-sensitive)"
ILIKE: "contains (case-insensitive)"
IN: ["value1", "value2"]
}

Numeric Filters:

savingAmount: {
GT: 100 # Greater than
GTE: 100 # Greater than or equal
LT: 1000 # Less than
LTE: 1000 # Less than or equal
EQ: 500 # Equal
}

Date Filters:

createdAt: {
GTE: "2024-01-01T00:00:00Z"
LTE: "2024-12-31T23:59:59Z"
}

Complex Filters:

where: {
OR: [
{ savingAmount: { GTE: 1000 } }
{
AND: [
{ savingAmount: { GTE: 500 } }
{ risk: { LTE: 3 } }
]
}
]
NOT: { status: { EQ: DISMISSED } }
}

Error Handling

All API responses follow standard GraphQL error formatting:

{
"errors": [
{
"message": "Error description",
"path": ["fieldName"],
"extensions": {
"code": "ERROR_CODE"
}
}
]
}

Common Error Codes:

  • VALIDATION - Input validation failed

  • UNAUTHENTICATED - Invalid or missing authentication token

  • FORBIDDEN - Insufficient permissions

  • NOT_FOUND - Referenced entity doesn't exist

  • CONFLICT - Duplicate entity or constraint violation

Best Practices:

  1. Always check the success field in mutation responses

  2. Parse the errors array for detailed error information

  3. Implement retry logic for transient failures

  4. Validate input on the client side before sending requests

  5. Log errors for debugging and monitoring



Common Workflows

Creating a Complete Team Structure

## Common Patterns

### 1. Creating a Complete Team Structure

```graphql
# Step 1: Create parent team
mutation {
engineering: createTeam(input: { name: "Engineering" }) {
id
}
}

# Step 2: Create child teams
mutation {
backend: createTeam(input: { name: "Backend Team" }) {
id
}
frontend: createTeam(input: { name: "Frontend Team" }) {
id
}
}

# Step 3: Establish hierarchy
mutation {
addChildTeamsToTeam(id: "engineering-uuid", childTeamIds: ["backend-uuid", "frontend-uuid"]) {
success
}
}

# Step 4: Add members
mutation {
addMembersToTeam(id: "backend-uuid", userIds: ["user1-uuid", "user2-uuid"]) {
success
}
}

Bulk User Creation

mutation BulkCreateUsers {
createUser(
input: [
{
email: "[email protected]"
firstName: "Developer"
lastName: "One"
role: MEMBER
teams: [{ id: "backend-team-uuid" }]
remoteAssistanceConsent: true
}
{
email: "[email protected]"
firstName: "Developer"
lastName: "Two"
role: MEMBER
teams: [{ id: "frontend-team-uuid" }]
remoteAssistanceConsent: true
}
]
) {
success
users {
id
email
teams {
name
}
}
}
}

Finding High-Value Opportunities

# Query opportunities with filters
query FindHighValueOpportunities {
opportunities(
where: {
status: { EQ: OPEN }
savingAmount: { GTE: 500 }
risk: { LTE: 3 }
}
orderBy: [{ savingAmount: DESC }]
limit: 20
) {
id
name
savingAmount
risk
resource {
name
service
}
}
}

# Export filtered opportunities
query ExportOpportunities {
opportunitiesExport(
where: {
status: { EQ: OPEN }
savingAmount: { GTE: 500 }
}
exportType: CSV
)
}

Did this answer your question?