Tabnine SCIM API
SCIM API key issued via the admin-only auth-service endpoint POST /organization/idp/scim-key. Token also encodes syncMode (e.g. UsersAndTeams), which gates Groups behavior as noted above.
Only userName eq "<value>" is supported. Any other property or operator returns 400. (scim.router.ts parseScimFilter)
Page size. Optional, passed through to auth-service (default 10 there).
1-based per SCIM spec. Converted to 0-based before calling the internal auth-service API.
OK. Deviation - no real pagination handling (AuthClient.getUsers has // TODO: handle pagination); totalResults may not reflect true dataset size across pages.
["urn:ietf:params:scim:api:messages:2.0:ListResponse"]Bad Request.
Missing/invalid bearer token, org mismatch, IDP sync disabled for the org, key ID mismatch, or key expired (verifyIdpKeyMiddleware in auth-service).
GET /scim/v2/Users HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:ListResponse"
],
"totalResults": 1,
"Resources": [
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"id": "text",
"externalId": "text",
"userName": "name@gmail.com",
"active": true,
"meta": {
"resourceType": "User",
"created": "2026-01-01T00:00:00.000Z",
"lastModified": "2026-01-01T00:00:00.000Z"
}
}
]
}SCIM API key issued via the admin-only auth-service endpoint POST /organization/idp/scim-key. Token also encodes syncMode (e.g. UsersAndTeams), which gates Groups behavior as noted above.
Required. Not validated as email format at this layer (only presence-checked).
Required.
Optional. Defaults to true downstream if omitted.
Created.
["urn:ietf:params:scim:schemas:core:2.0:User"]Missing userName or externalId. (These are the only two fields validated at runtime, despite meta.resourceType being typed as required — it is not enforced.)
Missing/invalid bearer token, org mismatch, IDP sync disabled for the org, key ID mismatch, or key expired (verifyIdpKeyMiddleware in auth-service).
Deviation from RFC (no standard SCIM 409 body defined) - a user with this userName already has an externalId set.
POST /scim/v2/Users HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 113
{
"schemas": [
"text"
],
"userName": "name@gmail.com",
"externalId": "text",
"active": true,
"meta": {
"resourceType": "User"
}
}{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"id": "text",
"externalId": "text",
"userName": "name@gmail.com",
"active": true,
"meta": {
"resourceType": "User",
"created": "2026-01-01T00:00:00.000Z",
"lastModified": "2026-01-01T00:00:00.000Z"
}
}SCIM API key issued via the admin-only auth-service endpoint POST /organization/idp/scim-key. Token also encodes syncMode (e.g. UsersAndTeams), which gates Groups behavior as noted above.
OK.
["urn:ietf:params:scim:schemas:core:2.0:User"]Missing/invalid bearer token, org mismatch, IDP sync disabled for the org, key ID mismatch, or key expired (verifyIdpKeyMiddleware in auth-service).
Not Found.
GET /scim/v2/Users/{id} HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"id": "text",
"externalId": "text",
"userName": "name@gmail.com",
"active": true,
"meta": {
"resourceType": "User",
"created": "2026-01-01T00:00:00.000Z",
"lastModified": "2026-01-01T00:00:00.000Z"
}
}Deviation - not a true full replace. Omitted fields are left unchanged rather than cleared (internal auth-service call is a PATCH, not a PUT).
SCIM API key issued via the admin-only auth-service endpoint POST /organization/idp/scim-key. Token also encodes syncMode (e.g. UsersAndTeams), which gates Groups behavior as noted above.
All fields optional (Partial - see auth.types.ts). No firstName/lastName at this layer.
OK.
["urn:ietf:params:scim:schemas:core:2.0:User"]A field outside {userName, externalId, active} was sent.
Not Found.
PUT /scim/v2/Users/{id} HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 63
{
"userName": "name@gmail.com",
"externalId": "text",
"active": true
}{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"id": "text",
"externalId": "text",
"userName": "name@gmail.com",
"active": true,
"meta": {
"resourceType": "User",
"created": "2026-01-01T00:00:00.000Z",
"lastModified": "2026-01-01T00:00:00.000Z"
}
}Deviation - this is a soft delete. The user is deactivated (toggleUserActive(..., false) in auth-service); the record is not removed. Re-provisioning: POSTing /Users again with the same userName reactivates/adopts the existing (deactivated) user rather than creating a new one or erroring, as long as it currently has no externalId set - if it still has one, POST returns 409 instead.
SCIM API key issued via the admin-only auth-service endpoint POST /organization/idp/scim-key. Token also encodes syncMode (e.g. UsersAndTeams), which gates Groups behavior as noted above.
No Content. Correctly empty-bodied (unlike the internal auth-service delete endpoint, which incorrectly sends a body on 204).
No content
Not Found.
DELETE /scim/v2/Users/{id} HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
No content
Deviation - only active, externalId, userName (case-insensitive path match) are patchable. Operations targeting any other path are silently ignored (logged, not rejected). If no operation targets a supported property, this is a silent no-op that returns the current user unchanged with a 200 - the caller cannot distinguish "applied" from "ignored" from the response alone.
SCIM API key issued via the admin-only auth-service endpoint POST /organization/idp/scim-key. Token also encodes syncMode (e.g. UsersAndTeams), which gates Groups behavior as noted above.
OK (see no-op deviation note above).
["urn:ietf:params:scim:schemas:core:2.0:User"]Unsupported op value (must be add/remove/replace).
Not Found.
PATCH /scim/v2/Users/{id} HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 56
{
"Operations": [
{
"op": "add",
"path": "text",
"value": null
}
]
}{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:User"
],
"id": "text",
"externalId": "text",
"userName": "name@gmail.com",
"active": true,
"meta": {
"resourceType": "User",
"created": "2026-01-01T00:00:00.000Z",
"lastModified": "2026-01-01T00:00:00.000Z"
}
}SCIM API key issued via the admin-only auth-service endpoint POST /organization/idp/scim-key. Token also encodes syncMode (e.g. UsersAndTeams), which gates Groups behavior as noted above.
Only displayName eq "<value>" is supported.
1-based, converted to 0-based internally.
Comma-separated attribute names to omit from each result (e.g. members).
Deviation - if the organization's IDP sync mode is not UsersAndTeams (i.e. group provisioning isn't enabled for that org/token), this returns 200 with an empty list rather than an error, masking the feature-flag state.
["urn:ietf:params:scim:api:messages:2.0:ListResponse"]Missing/invalid bearer token, org mismatch, IDP sync disabled for the org, key ID mismatch, or key expired (verifyIdpKeyMiddleware in auth-service).
GET /scim/v2/Groups HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"schemas": [
"urn:ietf:params:scim:api:messages:2.0:ListResponse"
],
"totalResults": 1,
"Resources": [
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"id": "text",
"externalId": "text",
"displayName": "text",
"members": [
{
"value": "text",
"display": "text",
"type": "User",
"ref": "text"
}
],
"meta": {
"resourceType": "Group",
"created": "2026-01-01T00:00:00.000Z",
"lastModified": "2026-01-01T00:00:00.000Z"
}
}
]
}Deviation - members is accepted in the request body's type but is never sent to auth-service on create; a created group always starts with no members (add members afterward via PATCH/PUT).
SCIM API key issued via the admin-only auth-service endpoint POST /organization/idp/scim-key. Token also encodes syncMode (e.g. UsersAndTeams), which gates Groups behavior as noted above.
Deviation (significant) - if the org's sync mode is not UsersAndTeams, this endpoint does NOT call auth-service at all. It fabricates a 201 response with a random UUID and echoes the input back. The caller is told the group was created; nothing was persisted.
["urn:ietf:params:scim:schemas:core:2.0:Group"]Missing externalId.
POST /scim/v2/Groups HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 134
{
"schemas": [
"text"
],
"displayName": "text",
"externalId": "text",
"members": [
{
"value": "text",
"display": "text",
"type": "User",
"ref": "text"
}
]
}{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"id": "text",
"externalId": "text",
"displayName": "text",
"members": [
{
"value": "text",
"display": "text",
"type": "User",
"ref": "text"
}
],
"meta": {
"resourceType": "Group",
"created": "2026-01-01T00:00:00.000Z",
"lastModified": "2026-01-01T00:00:00.000Z"
}
}SCIM API key issued via the admin-only auth-service endpoint POST /organization/idp/scim-key. Token also encodes syncMode (e.g. UsersAndTeams), which gates Groups behavior as noted above.
OK.
["urn:ietf:params:scim:schemas:core:2.0:Group"]Not found, OR sync mode is not UsersAndTeams (both cases return 404 here - inconsistent with GET /Groups, which returns an empty 200 list for the same disabled-sync-mode condition instead of an error).
GET /scim/v2/Groups/{id} HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"id": "text",
"externalId": "text",
"displayName": "text",
"members": [
{
"value": "text",
"display": "text",
"type": "User",
"ref": "text"
}
],
"meta": {
"resourceType": "Group",
"created": "2026-01-01T00:00:00.000Z",
"lastModified": "2026-01-01T00:00:00.000Z"
}
}SCIM API key issued via the admin-only auth-service endpoint POST /organization/idp/scim-key. Token also encodes syncMode (e.g. UsersAndTeams), which gates Groups behavior as noted above.
Deviation - if sync mode is not UsersAndTeams, fabricates a 200 echo of the input without persisting anything (same no-op pattern as POST /Groups).
["urn:ietf:params:scim:schemas:core:2.0:Group"]Not Found.
PUT /scim/v2/Groups/{id} HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 115
{
"displayName": "text",
"externalId": "text",
"members": [
{
"value": "text",
"display": "text",
"type": "User",
"ref": "text"
}
]
}{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"id": "text",
"externalId": "text",
"displayName": "text",
"members": [
{
"value": "text",
"display": "text",
"type": "User",
"ref": "text"
}
],
"meta": {
"resourceType": "Group",
"created": "2026-01-01T00:00:00.000Z",
"lastModified": "2026-01-01T00:00:00.000Z"
}
}Deviation - if sync mode is not UsersAndTeams, silently no-ops and returns 204 without calling auth-service.
SCIM API key issued via the admin-only auth-service endpoint POST /organization/idp/scim-key. Token also encodes syncMode (e.g. UsersAndTeams), which gates Groups behavior as noted above.
No Content.
No content
Not Found.
DELETE /scim/v2/Groups/{id} HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
No content
Supports standard Operations array. members path supports add/remove/replace, including value-filtered paths like members[value eq "<id>"]. Flat displayName/externalId replace also supported.
SCIM API key issued via the admin-only auth-service endpoint POST /organization/idp/scim-key. Token also encodes syncMode (e.g. UsersAndTeams), which gates Groups behavior as noted above.
OK (only reached when sync mode is UsersAndTeams).
["urn:ietf:params:scim:schemas:core:2.0:Group"]Deviation - if sync mode is not UsersAndTeams, silently returns 204 with no indication the patch was discarded.
Invalid member payload or unsupported operation.
Not Found.
PATCH /scim/v2/Groups/{id} HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Content-Type: application/json
Accept: */*
Content-Length: 56
{
"Operations": [
{
"op": "add",
"path": "text",
"value": null
}
]
}{
"schemas": [
"urn:ietf:params:scim:schemas:core:2.0:Group"
],
"id": "text",
"externalId": "text",
"displayName": "text",
"members": [
{
"value": "text",
"display": "text",
"type": "User",
"ref": "text"
}
],
"meta": {
"resourceType": "Group",
"created": "2026-01-01T00:00:00.000Z",
"lastModified": "2026-01-01T00:00:00.000Z"
}
}Known gap (referenced by DEV3-6023) - only User and Group core schemas are returned. An EnterpriseUser extension schema (employeeNumber attribute) exists fully drafted in source (consts.ts) but is commented out and not served. No custom-attribute extension schemas exist at all.
SCIM API key issued via the admin-only auth-service endpoint POST /organization/idp/scim-key. Token also encodes syncMode (e.g. UsersAndTeams), which gates Groups behavior as noted above.
OK.
GET /scim/v2/Schemas HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
OK.
{}SCIM API key issued via the admin-only auth-service endpoint POST /organization/idp/scim-key. Token also encodes syncMode (e.g. UsersAndTeams), which gates Groups behavior as noted above.
OK.
Not Found.
GET /scim/v2/Schemas/{id} HTTP/1.1
Authorization: Bearer YOUR_SECRET_TOKEN
Accept: */*
{}Last updated
Was this helpful?
