Create Space
You can create a space in your organization programmatically,
mutation createSpace(
$accountOrganizationId: ID!
$name: String!
$private: Boolean!
) {
createSpace(
input: {
accountOrganizationId: $accountOrganizationId
name: $name
private: $private
}
) {
space {
name
id
}
}
}
variables
{
"accountOrganizationId": "your_org_id",
"name": "space_name",
"private": true
}
Query for Users in an Organization
query getUserIDs{
node(id:"organization_id"){
... on AccountOrganization {
accountOrganizationUsers{
edges{
node{
user{
email
name
id
}
}
}
}
}
}
}
Delete Users from Space
mutation removeMemberFromSpace{
removeSpaceMember(input:
{
spaceId:"space_id" #desired space to delete user from
userId: "user_id" #returned from the query for users in an org
})
{
clientMutationId
}
}
Add Users to Space
mutation addMembertoSpace{
assignSpaceMembership(input:
{
spaceMemberships:[
{
userId: "user_id"
spaceId: "space_id" #desired space to add user
role: member #admin, member, readOnly
}
]
}){
spaceMemberships{
id
role
}
}
}
SAML Configuration
Manage SAML IdP configurations via GraphQL. There are three distinct workflows:
- Migration from File Config - Reading existing file-based config and creating a DB entry
- Fresh Creation - Creating a new SAML config from scratch
- Updating Existing Config - Modifying an existing DB-managed config
Prerequisites: Data Gathering Queries
Before creating or updating SAML configs, gather supporting data: organizations, spaces (mapped to orgs), and available roles.
List All SAML Configurations
Use this to find existing configs. Check isManagedByFile to determine which workflow to use.
query SAMLConfigsQuery {
account {
id
allSamlIdPs(first: 50, includeDeleted: true) {
edges {
node {
id
emailDomainsList {
id
domain
validated
}
accountId
metadataUrl
metadataXml
defaultOrgId
defaultOrgRoleId
defaultSpaceId
defaultSpaceRoleId
syncUserRoles
signAuthn
roleMappings {
id
attributesMap
isAccountAdmin
orgRole {
orgId
roleId
}
spaceRolesMap
spaceRbacRolesMap
}
enforceSaml
allowLoginWithDefaults
createdAt
createdByUserId
updatedAt
isManagedByFile
}
}
}
}
}
isManagedByFile: true indicates a file-based config that is read-only through the API. Use Workflow 1 to migrate it to a DB-managed config.
Query Organizations, Spaces, and Roles
Fetches the org→space mappings and available RBAC roles needed for role mapping configuration.
query OrganizationsSpacesQuery(
$orgCount: Int = 100
$spaceCount: Int = 100
$roleCount: Int = 100
) {
account {
id
organizations(first: $orgCount) {
edges {
node {
id
name
spaces(first: $spaceCount) {
edges {
node {
id
name
}
}
}
}
}
}
roles(first: $roleCount) {
edges {
node {
id
name
description
isPredefined
createdAt
updatedAt
permissions {
name
description
}
}
}
}
}
}
The roles query returns custom RBAC roles. isPredefined: true indicates Arize-managed roles that cannot be edited or deleted.
Example Response:
{
"data": {
"account": {
"id": "QWNjb3VudDoxMjM=",
"organizations": {
"edges": [
{
"node": {
"id": "QWNjb3VudE9yZ2FuaXphdGlvbjoxMjM=",
"name": "Engineering",
"spaces": {
"edges": [
{ "node": { "id": "U3BhY2U6NDU2", "name": "ML Production" } },
{ "node": { "id": "U3BhY2U6Nzg5", "name": "ML Staging" } }
]
}
}
}
]
},
"roles": {
"edges": [
{
"node": {
"id": "Um9sZToxMjM=",
"name": "Admin",
"description": "Full access",
"isPredefined": true,
"createdAt": "2024-01-01T00:00:00Z",
"updatedAt": "2024-01-01T00:00:00Z",
"permissions": [
{ "name": "space.manage", "description": "Manage space settings" }
]
}
},
{
"node": {
"id": "Um9sZTo0NTY=",
"name": "Viewer",
"description": "Read-only",
"isPredefined": false,
"createdAt": "2024-06-15T10:30:00Z",
"updatedAt": "2024-06-15T10:30:00Z",
"permissions": [
{ "name": "space.view", "description": "View space content" }
]
}
}
]
}
}
}
}
Workflow 1: Migrate File Config to Database
When isManagedByFile: true on an existing SAML config, you must create a new DB-managed config (not update). The file-based config is read-only through the API.
Read Existing Config Values
Use SAMLConfigsQuery above to read the file-managed config’s values.
Map to CreateSAMLIdPInput
Transform the queried config data into a create input:const fileConfig = queryResult.account.allSamlIdPs.edges[0].node;
const createInput = {
metadataUrl: fileConfig.metadataUrl, // OR metadataXml, not both
metadataXml: fileConfig.metadataXml,
emailDomainsList: fileConfig.emailDomainsList.map(d => ({
domain: d.domain,
validated: d.validated
})),
defaultOrgId: fileConfig.defaultOrgId,
defaultOrgRoleId: fileConfig.defaultOrgRoleId,
defaultSpaceId: fileConfig.defaultSpaceId,
defaultSpaceRoleId: fileConfig.defaultSpaceRoleId,
syncUserRoles: fileConfig.syncUserRoles,
signAuthn: fileConfig.signAuthn,
enforceSaml: fileConfig.enforceSaml,
allowLoginWithDefaults: fileConfig.allowLoginWithDefaults,
roleMappings: {
mappingsList: fileConfig.roleMappings?.map(rm => ({
attributesMap: rm.attributesMap,
isAccountAdmin: rm.isAccountAdmin,
orgRole: rm.orgRole ? {
orgId: rm.orgRole.orgId,
roleId: rm.orgRole.roleId
} : null,
spaceRolesMap: rm.spaceRolesMap,
spaceRbacRolesMap: rm.spaceRbacRolesMap
}))
}
};
Execute Create Mutation
See “Create SAML Configuration” below.
Workflow 2: Create New Config (Fresh)
Gather Support Data
Run OrganizationsSpacesQuery to get available orgs, spaces, and roles.
Execute Create Mutation
See “Create SAML Configuration” below.
Workflow 3: Update Existing DB Config
Updates are full replacements - you must send the complete configuration. Omitting fields may reset them to defaults.
List Configs to Get Target ID
Use SAMLConfigsQuery to find the config. Ensure isManagedByFile: false.
Gather Support Data
Run OrganizationsSpacesQuery for org→space mappings and role IDs.
Execute Update Mutation
See “Update SAML Configuration” below.
Create SAML Configuration
mutation CreateSAMLIdPMutation($input: CreateSAMLIdPInput!) {
createSAMLIdP(input: $input) {
idp {
id
emailDomainsList {
id
domain
validated
}
accountId
metadataUrl
metadataXml
defaultOrgId
defaultOrgRoleId
defaultSpaceId
defaultSpaceRoleId
syncUserRoles
signAuthn
roleMappings {
id
attributesMap
isAccountAdmin
orgRole {
orgId
roleId
}
spaceRolesMap
spaceRbacRolesMap
}
enforceSaml
allowLoginWithDefaults
createdAt
createdByUserId
updatedAt
}
error
}
}
Use allowLoginWithDefaults: true to allow users to log in without matching role mappings:{
"input": {
"emailDomainsList": [
{ "domain": "newcompany.com", "validated": false }
],
"metadataUrl": "https://idp.newcompany.com/saml2/metadata",
"allowLoginWithDefaults": true,
"defaultOrgId": "QWNjb3VudE9yZ2FuaXphdGlvbjoxMjM=",
"defaultOrgRoleId": "member",
"defaultSpaceId": "U3BhY2U6NDU2",
"defaultSpaceRoleId": "member"
}
}
{
"input": {
"emailDomainsList": [
{ "domain": "enterprise.com", "validated": false }
],
"metadataXml": "<?xml version=\"1.0\"?>...<EntityDescriptor>...</EntityDescriptor>",
"enforceSaml": true,
"allowLoginWithDefaults": false,
"syncUserRoles": true,
"signAuthn": true,
"defaultOrgId": "QWNjb3VudE9yZ2FuaXphdGlvbjoxMjM=",
"defaultOrgRoleId": "member",
"defaultSpaceId": "U3BhY2U6NDU2",
"defaultSpaceRoleId": "readOnly",
"roleMappings": {
"mappingsList": [
{
"attributesMap": [["memberOf", "cn=admins,ou=groups,dc=enterprise,dc=com"]],
"isAccountAdmin": true,
"orgRole": null,
"spaceRolesMap": [],
"spaceRbacRolesMap": []
},
{
"attributesMap": [["department", "data-science"]],
"isAccountAdmin": false,
"orgRole": {
"orgId": "QWNjb3VudE9yZ2FuaXphdGlvbjoxMjM=",
"roleId": "admin"
},
"spaceRolesMap": [
["U3BhY2U6NDU2", "admin"],
["U3BhY2U6Nzg5", "member"]
],
"spaceRbacRolesMap": []
},
{
"attributesMap": [["department", "ml-ops"]],
"isAccountAdmin": false,
"orgRole": {
"orgId": "QWNjb3VudE9yZ2FuaXphdGlvbjoxMjM=",
"roleId": "member"
},
"spaceRolesMap": [],
"spaceRbacRolesMap": [
["U3BhY2U6NDU2", "Um9sZToxMjM="],
["U3BhY2U6Nzg5", "Um9sZTo0NTY="]
]
}
]
}
}
}
Update SAML Configuration
mutation UpdateSAMLIdPMutation($input: UpdateSAMLIdPInput!) {
updateSAMLIdP(input: $input) {
idp {
id
emailDomainsList {
id
domain
validated
}
accountId
metadataUrl
metadataXml
defaultOrgId
defaultOrgRoleId
defaultSpaceId
defaultSpaceRoleId
syncUserRoles
signAuthn
roleMappings {
id
attributesMap
isAccountAdmin
orgRole {
orgId
roleId
}
spaceRolesMap
spaceRbacRolesMap
}
enforceSaml
allowLoginWithDefaults
createdAt
createdByUserId
updatedAt
}
error
}
}
Variables (Full Replacement):
{
"input": {
"id": "U0FNTElkUDoxMjM0NTY=",
"emailDomainsList": [
{ "domain": "company.com", "validated": true },
{ "domain": "subsidiary.com", "validated": false }
],
"metadataUrl": "https://idp.company.com/saml/metadata/v2",
"enforceSaml": true,
"allowLoginWithDefaults": false,
"syncUserRoles": true,
"signAuthn": true,
"defaultOrgId": "QWNjb3VudE9yZ2FuaXphdGlvbjoxMjM=",
"defaultOrgRoleId": "member",
"defaultSpaceId": "U3BhY2U6NDU2",
"defaultSpaceRoleId": "member",
"roleMappings": {
"mappingsList": [
{
"attributesMap": [["role", "platform-admin"]],
"isAccountAdmin": true,
"orgRole": null,
"spaceRolesMap": [],
"spaceRbacRolesMap": []
},
{
"attributesMap": [["team", "ml-eng"]],
"isAccountAdmin": false,
"orgRole": {
"orgId": "QWNjb3VudE9yZ2FuaXphdGlvbjoxMjM=",
"roleId": "admin"
},
"spaceRbacRolesMap": [
["U3BhY2U6NDU2", "Um9sZToxMjM="]
],
"spaceRolesMap": []
}
]
}
}
}
Clear All Role Mappings
To remove all role mappings, you must enable allowLoginWithDefaults:
{
"input": {
"id": "U0FNTElkUDoxMjM0NTY=",
"emailDomainsList": [{ "domain": "company.com", "validated": true }],
"enforceSaml": false,
"allowLoginWithDefaults": true,
"defaultOrgId": "QWNjb3VudE9yZ2FuaXphdGlvbjoxMjM=",
"defaultOrgRoleId": "member",
"defaultSpaceId": "U3BhY2U6NDU2",
"defaultSpaceRoleId": "member",
"roleMappings": {
"mappingsList": []
}
}
}
Delete SAML Configuration
mutation DeleteSAMLIdPMutation($input: DeleteSAMLIdPInput!) {
deleteSAMLIdP(input: $input) {
error
}
}
Variables:
{
"input": {
"id": "U0FNTElkUDoxMjM0NTY="
}
}
| Field | Type | Required | Description |
|---|
emailDomainsList | [EmailDomainInput!]! | Yes | At least one email domain |
metadataUrl | String | No* | URL to IdP metadata (mutually exclusive with metadataXml) |
metadataXml | String | No* | Raw XML metadata (mutually exclusive with metadataUrl) |
defaultOrgId | ID | No | Default organization for new users |
defaultOrgRoleId | ID | No | Default org role: "admin", "member", or custom role ID |
defaultSpaceId | ID | No | Default space for new users |
defaultSpaceRoleId | ID | No | Default space role |
syncUserRoles | Boolean | No | Sync roles on every login (default: false) |
signAuthn | Boolean | No | Sign SAML AuthN requests (default: false) |
enforceSaml | Boolean | No | Only allow SAML login (default: false) |
allowLoginWithDefaults | Boolean | No | Allow login without role mapping match |
roleMappings | RoleMappingsInput | No | SAML attribute → role mappings |
One of metadataUrl or metadataXml should be provided.
Same as CreateSAMLIdPInput plus:
| Field | Type | Required | Description |
|---|
id | ID! | Yes | Relay global ID of the config to update |
emailDomainsList | [EmailDomainInput] | No | Optional on update (null = keep existing) |
EmailDomainInput
| Field | Type | Required | Description |
|---|
domain | String! | Yes | Email domain (e.g., "company.com") |
id | ID | No | Optional ID for existing domains |
validated | Boolean | No | Domain validation status (Arize-internal) |
| Field | Type | Required | Description |
|---|
mappingsList | [RoleMappingInput] | No | List of role mapping rules |
| Field | Type | Required | Description |
|---|
id | ID | No | Optional ID for existing mappings |
attributesMap | [[String]] | No | SAML attribute key-value pairs: [["key", "value"], ...] |
isAccountAdmin | Boolean | No | Grant account admin privileges |
orgRole | OrgRoleInput | No | Organization role assignment |
spaceRolesMap | [[String]] | No | Legacy space roles: [["spaceId", "role"], ...] |
spaceRbacRolesMap | [[String!]!] | No | RBAC space roles: [["spaceId", "roleGlobalId"], ...] |
spaceRolesMap and spaceRbacRolesMap are mutually exclusive per mapping.
| Field | Type | Required | Description |
|---|
orgId | ID | No | Organization Relay global ID |
roleId | ID | No | Role: "admin", "member", or custom role ID |
Role ID Values
Organization Roles (orgRole.roleId)
Built-in roles for organization membership:
| Value | Description |
|---|
"admin" | Organization administrator - full org management access |
"member" | Organization member - standard access |
"readOnly" | Read-only organization access |
The annotator role is not available for organization roles in SAML role mappings. Annotators must be configured at the space level using spaceRolesMap.
Space Roles (spaceRolesMap values)
Built-in roles for space membership (legacy, use spaceRbacRolesMap for custom roles):
| Value | Description |
|---|
"admin" | Space administrator - full space management |
"member" | Space member - read/write access |
"readOnly" | Read-only space access |
"annotator" | Annotator role - can only access assigned labeling queues |
Note the camelCase: "readOnly" not "readonly". These values are case-sensitive.
RBAC Roles (spaceRbacRolesMap)
For custom RBAC roles, use Relay global IDs from the roles query:
query GetRoles {
account {
roles(first: 100) {
edges {
node {
id # Use this ID in spaceRbacRolesMap
name
description
isPredefined # true = Arize-managed, cannot be modified
}
}
}
}
}
Example mapping: [["U3BhY2U6NDU2", "Um9sZToxMjM="]] maps space ID to RBAC role ID.
Error Handling
All mutations return an error field. Check this before assuming success:
if (result.createSAMLIdP?.error) {
console.error("SAML config creation failed:", result.createSAMLIdP.error);
return;
}
// Success - use result.createSAMLIdP.idp
Common errors:
"Email domain already in use" - Domain registered to another config
"Role mappings required when allowLoginWithDefaults is false" - Need at least one mapping
"Cannot update file-managed SAML configuration" - Config has isManagedByFile: true
"Invalid metadata URL/XML" - Metadata parsing failed
Workflow Decision Tree
Does SAML config exist?
├── No → Workflow 2: Create New Config
└── Yes
└── Is isManagedByFile true?
├── Yes → Workflow 1: Migrate File to DB (Create new)
└── No → Workflow 3: Update Existing Config