Provision user accounts with SCIM

User provisioning is the process in Identity and Access Management which ensures that user accounts are created, changed, disabled and deleted in an automated fashion, dependent on staff turnover and changes within the organization. This helps to reduce the cost of identity management for IT teams and large organizations.

Zapier offers user provisioning support with the SCIM API, a protocol used by identity providers to manage people across a multitude of tools. It is also possible to use our SCIM API for managing the members of your team programmatically.

miscEye icon Note

User provisioning with SCIM is only available to customers on Zapier's Enterprise plan. To configure user provisioning, go to your user provisioning settings.

miscEye icon Note

Users created via SCIM will have their personal accounts hidden by default. If a team member wants to create a personal Zapier account, they must use a different email address to create that account.

 

What is SCIM?

SCIM is an open standard supported by various SaaS applications and identity providers, such as Okta and OneLogin. It runs on top of HTTP as REST API, in which the proper use of the verbs is paramount.

The base URL of the API is https://zapier.com/scim/v2, with all SCIM methods branching off from this base URL. In order to use the API, you will need to generate an API token. In order to do that, you need to go to the Provision tab in Zapier, enable user provisioning for your account and generate the corresponding API token. If you ever lose the token or you have reasons to believe that it is compromised, you can use the same page to regenerate it, marking the previous one as unavailable.

The API token must be included in an Authorization header with a type of Bearer as in Authorization: Bearer <your token>. Here is an example of a potential request to list all users belonging to your account:

GET https://zapier.com/scim/v2/Users
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>

{
    "itemsPerPage": 50,
    "startIndex": 1,
    "totalResults": 7,
    "Resources": [
        {
            "userName": "user@zapier.com",
            "meta": {
                "resourceType": "User",
                "lastModified": "2014-10-02T15:04:52+00:00",
                "location": "https://zapier.com/scim/v2/Users/1",
                "created": "2014-10-02T10:04:43+00:00"
            },
            "displayName": "Zaply Zap",
            "name": {
                "givenName": "Zaply",
                "formatted": "Zaply Zap",
                "familyName": "Zap"
            },
            "groups": [],
            "active": true,
            "id": 1,
            "emails": [
                {
                    "primary": true,
                    "value": "user@zap.com"
                }
            ],
            "schemas": [
                "urn:ietf:params:scim:schemas:core:2.0:User"
            ]
        },
   ....
   ]
}

Zapier supports the version 2.0 of the SCIM protocol.

 

Features

Zapier supports the following provisioning features.

  • Push New Users: New users created through your identity provider will also be created in Zapier.
  • Push Profile Updates: Updates made to the user's profile through your identity provider will be pushed to Zapier.
  • Push User Deactivation: Deactivating the user or deleting the user will deactivate the user in Zapier.
  • Reactivate User: Reactivated users also get reactivated in Zapier.

 

SCIM API endpoints

The SCIM API is a RESTful API with a predefined set of capabilities and a standardized output. There are two main resources that are usually exposed with a SCIM API, Users and Groups. The first one maps to team account members, while the second one maps to Teams workspaces. You can provision Teams workspaces membership as well as provision Teams.

You can use these APIs to add or remove members from your team account accordingly. If you use an identity provider for automatic user provisioning, the identity provider will take care of most of these details.

  • GET /ServiceProviderConfigs

Return the configuration details for our API, including which operations are supported.

  • GET /Schemas/Users

Returns configuration details for how users are formatted.

  • GET /Schemas/Groups

Returns configuration details for how team workspaces are formatted.

  • GET /Users

Returns a paginated list of users, fifty users per page by default. You can control the start and the number of users with the startIndex and count parameters.

This endpoint also has support for sorting, with the parameters sortBy, which requires a field to sort against, and sortOrder which can be either ascending or descending.

In case you want to filter out the returned attributes, you can use the attributes parameter, which should be a list of comma separated field names to return from the API.

Lastly, this endpoint also supports filtering the users with the filter parameter. Check the filter section for finding out what part of the SCIM filter DSL we support.

GET /scim/v2/Users?startIndex=1&count=50
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
  • POST /Users

Create a new member in your team account. This API requires at least userName to be passed, which needs to be an email address. If you use an Identity Provider for automatic user provisioning, make sure to configure it for sending the userName as an email address. In case there is already a user with the same email address, a 409 status code will be returned.

POST /scim/v2/Users
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    'schemas': ['urn:ietf:params:scim:schemas:core:2.0:User'],
    'userName': 'user@domain.com',
    'externalId': '1234',
    'name': {
        'formatted': 'User Name',
        'familyName': 'Name',
        'givenName': 'User',
    }
}

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "id": 1,
    "userName": "user@domain.com",
    "name": {
        "formatted": "User Name",
        "familyName": "Name",
        "givenName": "User",
    }
    "displayName": "User Name",
    "emails": [
        {
            "value": "user@domain.com",
            "primary": true
        },
    ],
    "timezone": "America/Chicago",
    "active":true
}
  • POST /Users/.search

You can use this endpoint in the same way as using the filter parameter with the GET /Users API, but with this one you submit the filter in the body of your request.

POST /scim/v2/Users
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    'filter': 'userName eq "user@username.com"',
    'attributes': ['id', 'userName'],
}
  • GET /Users/{id}

Retrieves a single member.

GET /scim/v2/Users/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
  • PATCH /Users/{id}

Updates an existing team member. Attributes that are not defined remain unchanged. You can use this endpoint to re-active a previously suspended account, by sending active set to true in your payload.

This API endpoint is a bit special, as it requires a particular format when sending the request. The spec mentions in great detail what the structure of a PATCH request should be. Right now we only support the Add and Replace operations.

Deactivate a user:

PATCH /scim/v2/Users/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [{"op": "Replace", "value": {"active": false}}]
}

Change the email address of a user:

PATCH /scim/v2/Users/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [
    {
        "op": "replace",
        "value": {
            "emails": [
                {
                    "value": "user@domain.com",
                    "type": "work",
                    "primary": true
                }
            ],
        },
    }
}
  • PUT /Users/{id}

Updates a single team member, overwriting all values even an attribute is empty or not provided.
You can use this endpoint to re-active a previously suspended account, by sending active set to true in your payload.

PUT /scim/v2/Users/id
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "userName": "user@domain.com",
    "externalId": "2341",
    "name": {
        "formatted": "Name User",
        "familyName": "User",
        "givenName": "Name",
    }
}

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
    "id": 1,
    "userName": "user@domain.com",
    "name": {
        "formatted": "Name User",
        "familyName": "User",
        "givenName": "Name",
    }
    "displayName": "User Name",
    "emails": [
        {
            "value": "user@domain.com",
            "primary": true
        },
    ],
    "timezone": "America/Chicago",
    "active":true
}
  • DELETE /Users/{id}

Deprovision a team member. We do not delete users with this endpoint, instead we mark them and their team membership as inactive. As such, they are not able to log in in Zapier until they are activated again. Deactivated users also will be hidden from future requests, but you can use PATCH and PUT to reprovision these users again.

DELETE /scim/v2/Users/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
  • GET /Groups

Returns a paginated list of teams, fifty groups per page by default. This endpoint supports
the same parameters for sorting, ordering, selection of returned attributes and partially
for filtering.

GET /scim/v2/Groups?startIndex=1&count=50
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
    "Resources": [
        "id": 1,
        "displayName": "Engineering",
        "members": [
            {"display": "a_member@domain.com", "value": 1},
            {"display": "another_member@domain.com", "value": 2},
        ],
        "id": 2,
        "displayName": "Marketing",
        "members": [
            {"display": "a_member@domain.com", "value": 1},
        ]
    ]
}
  • POST /Groups

Create a new team in your Enterprise account. This API requires at least displayName to be passed. In case there is a team with the same name, a 409 will be returned.

POST /scim/v2/Groups
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
    "displayName": "Engineering",
    "members": [
        {"display": "a_member@domain.com", "value": 1},
        {"display": "another_member@domain.com", "value": 2},
    ]
}

{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
    "id": 1,
    "displayName": "Engineering",
    "members": [
        {"display": "a_member@domain.com", "value": 1},
        {"display": "another_member@domain.com", "value": 2},
    ]
}
  • POST /Groups/.search

You can use this endpoint in the same way as using the filter parameter with the GET /Groups API, but with this one you submit the filter in the body of your request.

POST /scim/v2/Groups
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "filter": 'displayName eq "Engineering"',
    "attributes": ["members"],
}
  • GET /Groups/{id}

Retrieves a single team.

GET /scim/v2/Groups/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
  • PATCH /Groups/{id}

Updates an existing team. Attributes that are not defined remain unchanged.

This API endpoint is a bit special, as it requires a particular format when sending the request. The spec mentions in great detail what the structure of a PATCH request should be.

Change a team's name:

PATCH /scim/v2/Groups/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [
        {"op": "Replace", "value": {"displayName": "Marketing"}}]
}

Add one or multiple team members to the given team. $ref is optional, but if given, it should be
the full URL to the resource represented by the SCIM service provider API.

PATCH /scim/v2/Groups/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [
        {
            "op": "Add",
            "path": "members",
            "value": [
                {
                    'display': 'John Smith',
                    '$ref': 'https://zapier.com/v2/Users/1',
                    'value': 1,
                },
                {
                    'display': 'John Doe',
                    '$ref': 'https://zapier.com/v2/Users/2',
                    'value': 2,
                }
            ]
        }
    ]
}

Replace all members in a team with the given list:

PATCH /scim/v2/Groups/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [
        {
            "op": "Replace",
            "path": "members",
            "value": [
                {
                    'display': 'John Smith',
                    '$ref': 'https://zapier.com/v2/Users/1',
                    'value': 1,
                },
                {
                    'display': 'John Doe',
                    '$ref': 'https://zapier.com/v2/Users/2',
                    'value': 2,
                }
            ]
        }
    ]
}

Remove one or multiple members from a team:

PATCH /scim/v2/Groups/{id}
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:api:messages:2.0:PatchOp"],
    "Operations": [
        {
            "op": "Remove",
            "path": "members[value eq 'johndoe@domain.com']",
        },
        {
            "op": "Remove",
            "path": "members[value eq 'johnsmith@domain.com']",
        }
    ]
}
  • PUT /Groups/{id}

Updates a single team, overwriting its fields entirely.

 :::json
PUT /scim/v2/Groups/1
Host: zapier.com
Accept: application/scim+json, application/json
Authorization: Bearer <token>
{
    "schemas": ["urn:ietf:params:scim:schemas:core:2.0:Group"],
    "displayName": "Engineering",
    "members": [
        {"display": "a_member@domain.com", "value": 1},
        {"display": "another_member@domain.com", "value": 2},
    ]
}
  • DELETE /Groups/{id}

Deprovision a team and remove all of its memberships.

  • GET /Me

This API represents the owner of the account. The API will return a redirect to the corresponding user endpoint.

 

Timezone format

When supplied, timezones in provisioning requests are expected to be in the IANA format some examples of which are shown below:

'America/Los_Angeles'
'Europe/Amsterdam'
'UTC'

 

SCIM filter

The /Users and /Groups endpoint have support for filtering the resources by using the SCIM filter DSL specified in the SCIM protocol spec. The following rules apply to the filter parameter:

  • It must contain a valid boolean operator
  • It needs to respect the format attribute name, followed by attribute operator, followed by attribute value. As an example, filter=userName eq “user@zapier.com” is a valid filter.
  • Multiple expressions can be combined using two logical operators.
  • Expressions can be grouped together using "()"
  • String literals must be valid JSON strings.

Zapier supports the following operators:

eq  equal
co  contains
sw  starts with
gt  greater than
ge  greater than or equal
lt  less than
le  less than or equal
and logical And
or  logical Or

Here are some examples of filters you can use:

  • userName eq “user@example.com”
  • id eq 1234
  • id eq 1234 or userName co “@example.com”
  • userName sw user
  • displayName eq "Engineering"

 

Configuration steps

Configure your Provisioning settings for Zapier:

  • Go to your Settings, then navigate to User Provisioning in the left sidebar menu.
  • Click Enable to enable user provisioning.
  • Once user provisioning is enabled, a new authentication token will be generated. Use it to configure your identity provider to send the requests at the base SCIM URL, which is https://zapier.com/scim/v2.

If your identity provider requires a SCIM template, use the following JSON template:

{
    "schemas": [
        "urn:scim:schemas:core:1.0"
    ],
    "userName": "{$parameters.scimusername}",
    "active": "{$user.active}",
    "name": {
        "givenName": "{$user.firstname}",
        "familyName": "{$user.lastname}",
        "formatted": "{$user.display_name}"
    }
}

If everything went fine, you should see a screen similar to the following:
Enabled provisioning

 

Integrate with OneLogin

To integrate OneLogin SCIM and Zapier:

  • Add a new company app that uses SCIM, most likely SCIM Provisioner with SAML (SCIM v2). Alternatively, you can use the official OneLogin Zapier app for configuring both SAML and SCIM.
  • Once added, go to the Configuration tab and set the proper values.
  • For the SCIM Base URL field, use https://zapier.com/scim/v2/
  • For the SCIM Bearer Token field, use the token generated by you in the provisioning tab from Zapier.
  • Go to the Parameters tab and set the SCIM Username to be the username from OneLogin. We expect that the username is an email address. Yours should look like in this example:

OneLogin parameters

  • For the SCIM JSON Template field, use the following value:
{
    "schemas": [
        "urn:scim:schemas:core:1.0"
    ],
    "userName": "{$parameters.scimusername}",
    "active": "{$user.active}",
    "name": {
        "givenName": "{$user.firstname}",
        "familyName": "{$user.lastname}",
        "formatted": "{$user.display_name}"
    }
}

Once that is ready, go to the provisioning tab to enable it. You can opt to approve all the provisioning steps that OneLogin does, this might be useful to you depending or not if you want to test the user provisioning before enabling it for your entire account.

OneLogin provisioning

 

Integrate with Okta

To integrate Okta SCIM and Zapier:

  • Add a new company app for SCIM. You can use our early access Okta app, which offers both SAML and SCIM support.
  • Once added, enable provisioning and go to the provisioning tab.
  • Enable the corresponding capabilities, such as Create Users and Update User Attributes
  • In the attribute mappings section, make sure that the attribute mapping that Okta uses looks like the one from the screenshot:

Okta provisioning

 

Integrate with Microsoft Entra ID

Learn how to set up SCIM with Microsoft Entra ID.

 

Troubleshooting tips and limitations

  • The team owner cannot be de-provisioned. If you want to do that, you have to first transfer your Zapier account to someone else.
  • Users cannot be permanently deleted from Zapier, they will be deactivated instead. A deactivated user can be reactivated.
    • When a user is deactivated via SCIM, Zapier immediately deactivates their membership in your account and its teams, ensuring that their access is immediately revoked. All shared Zaps, app connections, and folders are transferred to the account owner. The user's private Zaps are paused.
  • Users cannot change their details on accounts that have user provisioning enabled.
  • Users cannot be created with domains that are not verified by the team. Domains can be verified under the Domains section in Settings.
  • The SCIM API is rate limited. If your requests are being limited, a 429 response will be returned.
  • The SCIM API does not support the full filter DSL as specified in the SCIM spec. We do support most of the common filters though, check the filter section on what exactly is supported.
  • The username must be the same as the email address in Zapier. For certain identity providers, these values can be configured separately, but if these values are not equal, we will raise an error during provisioning. Also, the username cannot be updated independently of the email, you need to update both in a single request, otherwise an error will be returned.
  • Because of SAML JIT, changing the username of a user in the identity provider could result in a new user being provisioned, as we use the email address to create or update users. If possible, configure your identity provider to send with the SAML attributes the internalId parameter, set to the internal ID of your identity provider. This should look along the lines of the following screenshot, depending on your identity provider:

internal_id

  • If sending an internalId is not possible, changing the username of a user will result in a new user being provisioned during SAML SSO JIT.
  • If no explicit timezone was defined for users, we either use UTC or Central Time depending on the context. A user that has a blank timezone in Zapier will also have a blank timezone in the identity provider. If it is possible for your identity provider, mark the timezone field as required, but do note that you will not be able to bulk import users that have no timezone set in Zapier.
  • Microsoft Active Directory Federation Services is not supported at this time.

If you have any issues with your setup or need further assistance, reach out to the Premier Support team.

Was this article helpful?
4 out of 4 found this helpful