SCIM provisioning
Probara serves SCIM 2.0 (RFC 7643 and RFC 7644) at https://app.probara.net/scim/v2. An identity provider uses it to create, update, deactivate and delete the people of one organization, and to push that organization’s groups. This page is the reference for the endpoint. To connect a provider in the app, read the SCIM provisioning guide.
SCIM is an Enterprise feature. On any other plan, every request with a valid token answers 403 with the detail SCIM requires the Enterprise plan.
Quick path
Section titled “Quick path”- Create a token on the SCIM page of the Workspace and copy its secret. Probara shows it once.
- Send
Authorization: Bearer <token>with every request tohttps://app.probara.net/scim/v2. - Check the connection with
GET /ServiceProviderConfig, which answers200withapplication/scim+json, and withGET /Users?count=1.
Base URL and authentication
Section titled “Base URL and authentication”| Topic | Behavior |
|---|---|
| Base URL | https://app.probara.net/scim/v2, the same for every organization. The token alone decides the organization. No organization id in the URL or in a header is read. |
| Token | Starts with probara_scim_, followed by 43 base64url characters. Created on the SCIM page of the Workspace, shown once, and valid for at most 365 days. An organization holds at most two active tokens. |
| Header | Authorization: Bearer <token>. Any other scheme is refused. |
| Scope | A SCIM token works only on /scim/v2. /api/v1 refuses it. |
| Refusal | 401 with WWW-Authenticate: Bearer. The detail is the same for a missing, unknown, revoked or expired token, so it never says which check failed. |
| Organization state | While an organization is suspended or scheduled for deletion, every write answers 403. Reads stay open. |
Endpoints
Section titled “Endpoints”| Method and path | Answer |
|---|---|
GET /ServiceProviderConfig | Capabilities. Patch and filter are supported, with up to 100 results per page. Bulk, password change, sort and ETag are not. |
GET /ResourceTypes, GET /ResourceTypes/{id} | The User and Group resource types. Any other id answers 404. |
GET /Schemas, GET /Schemas/{urn} | The User schema, its enterprise and Probara extensions, and the Group schema. Any other URN answers 404. |
GET /Users, POST /Users | List or create people. A create answers 201 with a Location header. |
GET /Users/{id}, PUT /Users/{id}, PATCH /Users/{id} | Read, replace or patch one person. |
DELETE /Users/{id} | Remove the person’s membership, if any, then the SCIM record. Answers 204 with no body. |
GET /Groups, POST /Groups | List or create groups. A create answers 201 with a Location header. |
GET /Groups/{id}, PUT /Groups/{id}, PATCH /Groups/{id} | Read, replace or patch one group. |
DELETE /Groups/{id} | Delete the group and its access. Answers 204 with no body. |
/Bulk, /Me, /.search | Answer 501. |
A trailing slash names the same path. A method the path does not accept answers 405 with an Allow header that lists the accepted methods. Any other path answers 404.
Filters
Section titled “Filters”| Resource | Filter | Matching |
|---|---|---|
| Users | userName eq "…" | Case-insensitive |
| Users | externalId eq "…" | Exact |
| Users | emails[type eq "work"].value eq "…" | Case-insensitive |
| Groups | displayName eq "…" | Case-insensitive |
| Groups | externalId eq "…" | Exact |
Conditions join with and. Attribute names and eq are case-insensitive. Inside a value, \" stands for a quote and \\ for a backslash. Any other filter answers 400 with scimType invalidFilter. A filter that matches nothing answers 200 with totalResults set to 0 and an empty Resources array, never 404.
Paging and attributes
Section titled “Paging and attributes”| Parameter | Behavior |
|---|---|
startIndex | One-based. A value below 1 reads as 1. A value that is not a whole number answers 400 with scimType invalidValue. |
count | Up to 100, and 100 when omitted. A larger value reads as 100, and a negative one as 0. A value that is not a whole number answers 400 with scimType invalidValue. |
| Order | Oldest first, by creation time and then by id. The order is the same on every page. |
attributes | Returns only the named attributes. |
excludedAttributes | Drops the named attributes. Probara supports excludedAttributes=members on groups. |
schemas, id and meta are always returned. A URN with a sub-attribute, such as urn:ietf:params:scim:schemas:extension:enterprise:2.0:User:department, selects only that sub-attribute. totalResults counts every match, and itemsPerPage counts the resources on the page.
Attributes
Section titled “Attributes”| Attribute | Behavior |
|---|---|
userName | Required on create and replace. Unique per organization, compared case-insensitively. |
emails (type work) | The work address, which must be an email address. When there is no work address, userName must be an email address, and it serves as the address. |
active | A boolean, or the string "True" or "False" in any case. Defaults to true on create. |
externalId, displayName, title, name.givenName, name.familyName, name.formatted | Stored per organization. The person’s global profile is never changed. |
Enterprise department and employeeNumber | Stored per organization. |
Probara role and Entra roles | Role values. See Roles. |
password | Ignored. Probara does not sync passwords. |
groups | Ignored in a user body. Group membership is pushed through /Groups. |
Create and replace
Section titled “Create and replace”POST and PUT take the whole user. PUT clears every attribute the body leaves out.
A POST for an address that is already a member of the organization adopts that membership into the new record, so nobody is added twice. A POST whose userName or work address another record of the organization already holds answers 409 with scimType uniqueness.
A person on one of the organization’s verified domains gets an account and a membership in the same change, in the role that Roles gives. A person elsewhere receives an invitation, and their record stays unlinked until they accept it.
PATCH takes an Operations array. op is add, replace or remove, in any case. The operations apply in order, and one refused operation refuses the whole request.
| Path | Behavior |
|---|---|
active | Sets the state. Deactivation and reactivation are described below. |
userName, externalId, displayName, title, name.givenName, name.familyName, name.formatted | Set the value. remove clears it, except userName, which answers 400 with scimType invalidValue. |
emails[type eq "work"].value, emails | Set the work address. |
department, employeeNumber, and their enterprise URN forms | Set the value. |
| The role paths described in Roles | Set the role. |
emails[type eq "home"], password, groups | Ignored. |
| Any other path | Answers 400 with scimType invalidPath. |
A replace without a path takes an object of attributes, the Okta form. Its keys are read as attribute paths. If the object carries the resource itself, its id, schemas and meta are skipped and change nothing, on users and groups alike.
Address changes
Section titled “Address changes”The address of a person is the work email, or userName when no work email is set. Changing it is allowed only when the old and the new address are both on the organization’s verified domains and the account belongs to no other organization. Otherwise the answer is 400 with scimType mutability and a reason. A change to userName alone, while a work email holds the address, only changes the label.
Deactivation, reactivation and delete
Section titled “Deactivation, reactivation and delete”| Change | Effect |
|---|---|
active set to false (PATCH or PUT) | The membership is kept, deactivated: the person’s next request to the organization is refused, and the seat is freed. Their role, project access and groups stay. Sessions created through the organization’s single sign-on connection end. Personal API tokens and OAuth and MCP grants for the organization are revoked. Open run assignments and pending review requests are unassigned. The SCIM record stays, inactive, and is still returned by GET and by filters. |
active set to true | The same id returns. The membership is active again with its role, which the groups, the attribute or the default role give, after a seat check. Under Managed in Probara the role stays. Remembered groups are restored. Revoked tokens and grants are not restored. |
DELETE | The membership is removed, so the seat is freed, the person’s access ends, and their groups and open work go with it. Then the SCIM record is removed. The account stays. The id answers 404 afterwards. |
In every case the account stays. Organization CI app tokens are not affected. Cases, suites, runs, results, defects, comments and reviews the person created stay, and they still name the person.
The owner of an organization cannot be deprovisioned. A deactivation or a DELETE of the owner answers 400 with the detail The organization owner can't be deprovisioned by SCIM. Transfer ownership first. and writes nothing.
Groups
Section titled “Groups”Each group the identity provider sends becomes a Probara user group that the provider manages.
- Name and members come from the identity provider. In Probara, the description and the project, dashboard and saved query grants of the group stay editable. Renaming, deleting or changing the members of the group in Probara answers
409. - Members are applied only when they have a linked account and are active in the organization. Other members are remembered, and they join the Probara group when they become active.
- Name clashes. A group name that matches a group someone created in Probara, ignoring case, answers
409withscimTypeuniqueness. Nothing is written. PUTreplaces the name, theexternalIdand the whole member list.PATCHwithaddorremovechanges only the people it names. Areplaceonmemberssets the whole list. Removing someone who is not a member does nothing.
| Member operation | Form |
|---|---|
| Remove one member | remove with the path members[value eq "<id>"] |
| Remove several members | remove with the path members and a value array of {"value": "<id>"} objects |
| Remove every member | remove with the path members and no value |
| Replace the list | replace with the path members and a value array |
A member value that is not a Users id of this organization answers 400 with scimType invalidValue.
DELETE removes the Probara group and its project, dashboard and saved query grants. Group-to-role mapping is not part of this resource. It is set in the SCIM settings of the Workspace.
The role source of the organization decides which of the identity provider’s data sets a person’s role.
| Role source | The role comes from | When a person has no value |
|---|---|---|
groups (default) | The mapped group with the lowest priority number. Among groups that share it, the role that grants more permissions. | The organization’s default role |
attribute | The Probara role value, or the Entra roles values. Several values resolve to the role that grants the most permissions, and a tie goes to the lower slug. | The organization’s default role |
probara | Nothing. SCIM sets the role when the person is provisioned, and later updates do not change it. | Not applicable |
The default role is the one the organization’s single sign-on policy gives new members. It is Viewer until you change it.
Role shapes
Section titled “Role shapes”Under the attribute source, a role comes in one of these shapes, on POST, PUT and PATCH:
{ "schemas": [ "urn:ietf:params:scim:schemas:core:2.0:User", "urn:ietf:params:scim:schemas:extension:probara:2.0:User" ], "userName": "ada@example.com", "urn:ietf:params:scim:schemas:extension:probara:2.0:User": { "role": "member" }}{ "roles": [{ "value": "member" }] }Entra can also send roles as a JSON-encoded app role object, as a JSON-encoded string of the array, or as a plain string. Each form resolves to the role value it carries.
| Rule | Behavior |
|---|---|
| Value | A role slug of the organization: admin, member, viewer, or a custom role’s identifier. |
owner | Never assigned. Under attribute it answers 400 with scimType invalidValue. |
| Unknown slug | Under attribute it answers 400 with scimType invalidValue. |
| Other sources | Under groups and probara, a role value changes no role and never refuses the request. |
On PATCH, the Probara path is urn:ietf:params:scim:schemas:extension:probara:2.0:User:role, and roles is the Entra path. add adds to the stored role, remove clears it, and replace sets it. A value filter on roles answers 400 with scimType invalidPath.
Errors
Section titled “Errors”Every error uses the SCIM error schema, with status as a string:
{ "schemas": ["urn:ietf:params:scim:api:messages:2.0:Error"], "status": "409", "scimType": "uniqueness", "detail": "A user with this userName already exists in this organization."}The detail is written for the administrator, and an identity provider can show it in its log. scimType appears only where the table names one.
| Status | When | scimType |
|---|---|---|
400 | A malformed body, filter, path or value, an owner refusal, or a refused address change | invalidSyntax, invalidFilter, invalidPath, invalidValue, noTarget or mutability, when the table names one |
401 | A missing, unknown, revoked or expired token | None |
403 | The Enterprise plan is missing, the organization is suspended or scheduled for deletion, or no seat is free | None |
404 | An unknown id, resource type, schema or path | None |
405 | A method the path does not accept. The Allow header lists the accepted methods. | None |
409 | A duplicate userName, email or group name, or a group name that a group created in Probara holds | uniqueness |
413 | A body larger than 1 MB | None |
415 | A body sent with a media type other than application/scim+json or application/json | None |
429 | The token reached its request limit. The Retry-After header gives the wait in seconds. | None |
500 | An unexpected fault. Retry the request. | None |
501 | /Bulk, /Me or /.search | None |
Responses use application/scim+json; charset=utf-8. A request with a body must use application/scim+json or application/json, with or without parameters.
Limits
Section titled “Limits”| Limit | Value |
|---|---|
| Request body | 1 MB. A larger body answers 413. |
| Requests per token | 250 per 10 seconds, which is 25 per second. Above that, the answer is 429 with Retry-After: 10. |
| Page size | Up to 100 resources per page |
| Token expiry | Required, at most 365 days |
| Active tokens | Two per organization |
Checklist
Section titled “Checklist”-
GET /ServiceProviderConfiganswers200with your token. -
POST /Usersanswers201with aLocationheader, and a second create with the sameuserNameanswers409. - A
PATCHthat setsactivetofalseanswers200and keeps the record inGET /Users. - A request without a valid token answers
401.
Next step
Section titled “Next step”Read the SCIM provisioning guide for the setup steps for Okta, Microsoft Entra ID and generic SCIM 2.0 clients.