Skip to content

Identity Provider API

This page documents the key API endpoints for VeraID’s v2.0 Identity Provider capabilities. All endpoints require authentication via API key (Bearer token) unless otherwise noted. OIDC and SAML protocol endpoints are accessed by end users and service providers, not API keys.

Auth endpoints

Endpoints for managing authentication configuration and methods.

Password policy

MethodEndpointDescription
GET/api/v1/auth/password-policyGet current password policy
PUT/api/v1/auth/password-policyUpdate password policy

TOTP configuration

MethodEndpointDescription
GET/api/v1/auth/totp-configGet TOTP configuration
PUT/api/v1/auth/totp-configUpdate TOTP configuration

WebAuthn / Passkeys

MethodEndpointDescription
GET/api/v1/auth/webauthn-configGet WebAuthn configuration
PUT/api/v1/auth/webauthn-configUpdate WebAuthn configuration
GET/api/v1/auth/webauthn/users/{userId}/credentialsList a user’s registered passkeys
DELETE/api/v1/auth/webauthn/users/{userId}/credentials/{credId}Remove a user’s passkey
MethodEndpointDescription
GET/api/v1/auth/magic-link-configGet magic link configuration
PUT/api/v1/auth/magic-link-configUpdate magic link configuration

Social login providers

MethodEndpointDescription
GET/api/v1/auth/social-providersList configured social providers
POST/api/v1/auth/social-providersAdd a social login provider
PATCH/api/v1/auth/social-providers/{providerId}Update a social provider
DELETE/api/v1/auth/social-providers/{providerId}Remove a social provider

OIDC Provider endpoints

Client registration

These are the dashboard’s own endpoints: they take a signed-in session, not an API key. Any member may list and read clients; everything else requires an Admin or Owner. {id} is the client’s VeraID id, not its OAuth client_id.

MethodEndpointDescription
GET/api/v1/oidc-clientsList OIDC clients
POST/api/v1/oidc-clientsRegister a new OIDC client
GET/api/v1/oidc-clients/{id}Get client details
PATCH/api/v1/oidc-clients/{id}Update client configuration
DELETE/api/v1/oidc-clients/{id}Delete an OIDC client
POST/api/v1/oidc-clients/{id}/secretRotate the client secret (confidential clients)
POST/api/v1/oidc-clients/{id}/enableEnable a client
POST/api/v1/oidc-clients/{id}/disableDisable a client
GET/api/v1/oidc-clients/{id}/policiesConditional Access policies that apply to the client

Protocol endpoints (accessed by relying parties, not API keys)

The discovery document lists them all; point your OIDC library at it rather than hard-coding paths.

MethodEndpointDescription
GET/api/oidc/{orgId}/.well-known/openid-configurationOIDC discovery document
GET/api/oidc/{orgId}/jwksJSON Web Key Set
GET/api/oidc/{orgId}/authAuthorization endpoint
POST/api/oidc/{orgId}/tokenToken endpoint
GET/api/oidc/{orgId}/meUserInfo endpoint
POST/api/oidc/{orgId}/token/revocationToken revocation endpoint
GET/api/oidc/{orgId}/session/endEnd session (logout) endpoint
POST/api/oidc/{orgId}/device/authDevice authorization endpoint
GET/api/oidc/{orgId}/deviceDevice verification page, where the user enters and approves a device’s code (the verification_uri)
POST/api/oidc/{orgId}/token/introspectionToken introspection endpoint
POST/api/oidc/{orgId}/requestPushed authorization requests

At the token, introspection and revocation endpoints a confidential client authenticates with HTTP Basic (client_secret_basic); a public client sends only its client_id and uses PKCE. See OIDC Provider.


Directory endpoints

Users

MethodEndpointDescription
GET/api/v1/directory/usersList users (supports filtering, pagination)
POST/api/v1/directory/usersCreate a new user
GET/api/v1/directory/users/{userId}Get user details
PATCH/api/v1/directory/users/{userId}Update user attributes
DELETE/api/v1/directory/users/{userId}Delete a user
POST/api/v1/directory/users/{userId}/suspendSuspend a user
POST/api/v1/directory/users/{userId}/reactivateReactivate a suspended user
POST/api/v1/directory/users/{userId}/deprovisionPermanently deprovision a user

Query parameters for GET /api/v1/directory/users:

ParameterTypeDescription
statusstringFilter by status: INVITED, ACTIVE, SUSPENDED, DEPROVISIONED
groupstringFilter by group membership
searchstringSearch by name or email
pagenumberPage number (default: 1)
limitnumberItems per page (default: 20, max: 100)

Groups

MethodEndpointDescription
GET/api/v1/directory/groupsList groups
POST/api/v1/directory/groupsCreate a new group
GET/api/v1/directory/groups/{groupId}Get group details
PATCH/api/v1/directory/groups/{groupId}Update a group
DELETE/api/v1/directory/groups/{groupId}Delete a group
GET/api/v1/directory/groups/{groupId}/membersList group members
POST/api/v1/directory/groups/{groupId}/membersAdd members to a group
DELETE/api/v1/directory/groups/{groupId}/members/{userId}Remove a member from a group

SCIM 2.0 endpoints

SCIM endpoints follow the RFC 7644 specification. Authentication uses the SCIM bearer token, not the standard API key.

Users

MethodEndpointDescription
GET/api/scim/v2/{orgId}/UsersList or search users
POST/api/scim/v2/{orgId}/UsersCreate a user
GET/api/scim/v2/{orgId}/Users/{id}Get a user
PUT/api/scim/v2/{orgId}/Users/{id}Replace a user
PATCH/api/scim/v2/{orgId}/Users/{id}Update a user
DELETE/api/scim/v2/{orgId}/Users/{id}Delete a user

Groups

MethodEndpointDescription
GET/api/scim/v2/{orgId}/GroupsList or search groups
POST/api/scim/v2/{orgId}/GroupsCreate a group
GET/api/scim/v2/{orgId}/Groups/{id}Get a group
PUT/api/scim/v2/{orgId}/Groups/{id}Replace a group
PATCH/api/scim/v2/{orgId}/Groups/{id}Update a group (add/remove members)
DELETE/api/scim/v2/{orgId}/Groups/{id}Delete a group

Service Provider Configuration

MethodEndpointDescription
GET/api/scim/v2/{orgId}/ServiceProviderConfigSCIM service provider configuration
GET/api/scim/v2/{orgId}/SchemasSupported SCIM schemas
GET/api/scim/v2/{orgId}/ResourceTypesSupported resource types

SCIM filtering

The GET /Users and GET /Groups endpoints support SCIM filter expressions:

GET /api/scim/v2/{orgId}/Users?filter=userName eq "jane@example.com"
GET /api/scim/v2/{orgId}/Users?filter=name.familyName co "Smith"
GET /api/scim/v2/{orgId}/Groups?filter=displayName eq "Engineering"

Supported operators: eq, ne, co, sw, ew, gt, ge, lt, le, and, or, not.

SCIM token management

MethodEndpointDescription
GET/api/v1/directory/scim/tokensList SCIM tokens
POST/api/v1/directory/scim/tokensCreate a SCIM token
DELETE/api/v1/directory/scim/tokens/{tokenId}Revoke a SCIM token

SAML endpoints

Service Provider management

MethodEndpointDescription
GET/api/v1/saml/service-providersList SAML service providers
POST/api/v1/saml/service-providersRegister a new SP
GET/api/v1/saml/service-providers/{spId}Get SP details
PATCH/api/v1/saml/service-providers/{spId}Update SP configuration
DELETE/api/v1/saml/service-providers/{spId}Delete an SP

Protocol endpoints (accessed by service providers)

MethodEndpointDescription
GET/api/saml/{orgId}/metadataIdP metadata document (XML)
GET/POST/api/saml/{orgId}/ssoSingle Sign-On endpoint (accepts GET for redirect binding, POST for POST binding)
GET/POST/api/saml/{orgId}/sloSingle Logout endpoint

Federation endpoints

OIDC federation

MethodEndpointDescription
GET/api/v1/federation/oidcList OIDC federation connections
POST/api/v1/federation/oidcCreate an OIDC federation connection
GET/api/v1/federation/oidc/{id}Get connection details
PATCH/api/v1/federation/oidc/{id}Update connection
DELETE/api/v1/federation/oidc/{id}Delete connection
POST/api/v1/federation/oidc/{id}/testTest connection
GET/api/v1/federation/oidc/{id}/callbackOIDC callback (used by external IdP)

SAML federation

MethodEndpointDescription
GET/api/v1/federation/samlList SAML federation connections
POST/api/v1/federation/samlCreate a SAML federation connection
GET/api/v1/federation/saml/{id}Get connection details
PATCH/api/v1/federation/saml/{id}Update connection
DELETE/api/v1/federation/saml/{id}Delete connection
POST/api/v1/federation/saml/{id}/testTest connection
GET/api/v1/federation/saml/{id}/metadataSP metadata for this connection
POST/api/v1/federation/saml/{id}/acsACS endpoint for this connection

Domain management

MethodEndpointDescription
GET/api/v1/federation/domainsList domain-to-IdP mappings
POST/api/v1/federation/domains/{domain}/verifyVerify domain ownership

General federation

MethodEndpointDescription
GET/api/v1/federationList all federation connections (OIDC + SAML)
GET/api/v1/federation/{id}Get any federation connection by ID
PATCH/api/v1/federation/{id}Update status (enable/disable)
DELETE/api/v1/federation/{id}Delete any federation connection
POST/api/v1/federation/{id}/testTest any federation connection

Conditional access endpoints

MethodEndpointDescription
GET/api/v1/conditional-access/policiesList conditional access policies
POST/api/v1/conditional-access/policiesCreate a policy
GET/api/v1/conditional-access/policies/{id}Get policy details
PATCH/api/v1/conditional-access/policies/{id}Update a policy
DELETE/api/v1/conditional-access/policies/{id}Delete a policy
POST/api/v1/conditional-access/simulateSimulate policy evaluation
GET/api/v1/conditional-access/named-locationsList named locations
POST/api/v1/conditional-access/named-locationsCreate a named location
PATCH/api/v1/conditional-access/named-locations/{id}Update a named location
DELETE/api/v1/conditional-access/named-locations/{id}Delete a named location

Common request/response patterns

Creating an OIDC client

Done in Settings > OIDC Clients, which sends POST /api/v1/oidc-clients with the signed-in Admin or Owner session (not an API key).

Request body:

{
"clientName": "My Web App",
"clientType": "CONFIDENTIAL",
"applicationType": "web",
"redirectUris": ["https://app.example.com/callback"],
"scopes": ["openid", "profile", "email"]
}

clientType decides how the client authenticates: CONFIDENTIAL clients get a secret and use client_secret_basic; PUBLIC clients get none and use PKCE alone. It cannot be changed later.

Response (201 Created, abridged):

{
"data": {
"client": {
"id": "b3c1e2d4-…",
"clientId": "veraid_AbC123…",
"clientName": "My Web App",
"clientType": "CONFIDENTIAL",
"applicationType": "web",
"tokenEndpointAuthMethod": "client_secret_basic",
"redirectUris": ["https://app.example.com/callback"],
"grantTypes": ["authorization_code"],
"scopes": ["openid", "profile", "email"],
"requirePkce": true,
"requireConsent": true,
"createdAt": "2026-10-07T10:00:00.000Z"
},
"clientSecret": "shown-once"
}
}

The secret is returned once and stored only as a hash.

Creating a SCIM user (inbound)

Request (from external IdP):

Terminal window
curl -X POST https://app.veraid.io/api/scim/v2/{orgId}/Users \
-H "Authorization: Bearer scim_tok_abc123" \
-H "Content-Type: application/scim+json" \
-d '{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"userName": "jane@example.com",
"name": {
"givenName": "Jane",
"familyName": "Smith"
},
"emails": [
{ "value": "jane@example.com", "primary": true }
],
"active": true
}'

Response (201 Created):

{
"schemas": ["urn:ietf:params:scim:schemas:core:2.0:User"],
"id": "usr_abc123",
"userName": "jane@example.com",
"name": {
"givenName": "Jane",
"familyName": "Smith"
},
"emails": [
{ "value": "jane@example.com", "primary": true }
],
"active": true,
"meta": {
"resourceType": "User",
"created": "2026-03-26T10:00:00Z",
"lastModified": "2026-03-26T10:00:00Z",
"location": "https://app.veraid.io/api/scim/v2/{orgId}/Users/usr_abc123"
}
}

Simulating conditional access

Request:

Terminal window
curl -X POST https://app.veraid.io/api/v1/conditional-access/simulate \
-H "Authorization: Bearer kd_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"userId": "usr_abc123",
"application": "admin-dashboard",
"context": {
"ipAddress": "198.51.100.42",
"deviceTrust": "compliant",
"riskScore": 25
}
}'

Response (200 OK):

{
"evaluatedPolicies": [
{
"policyId": "pol_abc123",
"policyName": "Corporate network only",
"matched": false,
"reason": "IP is within allowed corporate range"
}
],
"finalAction": "allow"
}

Error codes specific to IdP endpoints

CodeErrorDescription
OIDC_CLIENT_NOT_FOUND404The specified OIDC client does not exist
INVALID_REDIRECT_URI400Redirect URI does not match registered URIs
INVALID_GRANT_TYPE400Grant type not allowed for this client
SP_NOT_FOUND404SAML service provider not found
SAML_SIGNATURE_INVALID400SAML request signature validation failed
FEDERATION_CONN_FAILED502Cannot reach the external IdP
DOMAIN_NOT_VERIFIED400Domain has not been verified for federation
SCIM_TOKEN_EXPIRED401SCIM bearer token has expired
SCIM_FILTER_INVALID400Invalid SCIM filter expression
POLICY_CONFLICT409Conditional access policy priority conflict