Service Provider Creation API — User Guide
The SP Creation API lets your own systems create and manage biometric service providers (SPs) programmatically, without anyone logging into the iPortal UI.
Access works in two layers:
- A portal admin at your company creates one or more service accounts from iPortal. Each service account is a long-lived credential pair (a Service Account Key + a Secret).
- Your system exchanges those credentials for a short-lived access token, then uses the token to create service providers and reset their credentials.
All actions are scoped to the company that owns the service account — the company is always derived from your credentials and can never be supplied in a request body.
Prerequisite: Your company must have the SP Creation API feature enabled. If it is not, every endpoint returns
403with internal code104031. Contact iProov to have it enabled.
Base URL
https://<your-iproov-region-host>/management
Replace the host with the one provided to you by iProov for your region.
All requests and responses are JSON (Content-Type: application/json), except
POST /auth/token, which uses HTTP Basic authentication.
Authentication
Every call to this API is made by a service account — the long-lived credential pair (Service Account Key + Secret) your system holds. A portal admin first creates that service account in the iPortal UI (see section 1); that is a one-time setup step, not part of this API.
| Step | Credential |
|---|---|
POST /auth/token | HTTP Basic — serviceAccountKey:secret |
| All other endpoints | Authorization: Bearer <access token> |
The typical machine-to-machine flow is:
Service Account Key + Secret ──POST /auth/token──▶ access token (JWT, 15 min)
access token ──Bearer──────────▶ POST /service-providers, …
Access tokens expire after 15 minutes. Request a new one when it expires.
1. Get your credentials (in iPortal)
Service accounts are created and managed by a portal admin at your company directly in the iPortal UI (Resources → Service Accounts) — this is a one-time setup step, not something your integration calls.
Creating a service account produces the two values this API needs:
- Service Account Key — the account's identifier (the
idfield in iPortal). You use it as the username for HTTP Basic auth onPOST /auth/token. - Secret — the password half of the pair. Shown only once at creation; store it immediately. If it is lost, the admin can reset it from the same screen.
Every service account is granted a fixed set of permissions
(ROLE_CREATE_COMPANY_SERVICE_PROVIDERS and
ROLE_RESET_COMPANY_SERVICE_PROVIDER_CREDENTIALS), scoped to that admin's
company.
The service-account management operations (create / list / reset-secret / delete) are iPortal UI actions, authenticated by the admin's browser session. They are not part of the programmable API and cannot be called with a service-account access token.
2. Get an access token
Exchange a service account's credentials for a short-lived access token.
POST /auth/token
Authentication: HTTP Basic. Send serviceAccountKey:secret, Base64-encoded,
in the Authorization header.
Request
POST /management/auth/token
Authorization: Basic <base64(serviceAccountKey:secret)>
Response — 200 OK
{
"jwt": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"expires_in": 900
}
| Field | Type | Description |
|---|---|---|
jwt | string | RS256 access token. Use it as Authorization: Bearer <jwt>. |
expires_in | number | Token lifetime in seconds (always 900 = 15 minutes). |
Errors
| Status | Internal code | When |
|---|---|---|
401 | 104010 | Missing or malformed Authorization header. |
401 | 104011 | Unknown service account, wrong secret, or the account is inactive. |
403 | 104031 | Your company's SP Creation API access has been revoked. |
For security, an inactive account and a wrong secret return the same
104011error — the API never reveals which one it was.
3. Service providers
These endpoints require a service account access token obtained in section 2.
Authorization: Bearer <access token>
3.1 Create a service provider
POST /service-providers
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Human-readable label for the SP. |
description | string | no | Optional free-text description. |
environment | string | yes | One of dev, test, prod. |
cluster | string | yes | Full cluster host the SP lives on. |
clusteris the full cluster host, not a short region code — e.g.beta.rp.secure.iproov.me. Valid cluster hosts are environment- and region-specific; iProov provides the correct host(s) for your account.
{
"name": "Onboarding SP",
"description": "Customer onboarding flow",
"environment": "prod",
"cluster": "beta.rp.secure.iproov.me"
}
Response — 200 OK
{
"id": "…",
"name": "Onboarding SP",
"description": "Customer onboarding flow",
"apiKey": "…",
"apiSecretPrimary": "…",
"oauthUser": "…",
"oauthPasswordPrimary": "…",
"cluster": "beta.rp.secure.iproov.me",
"environment": "prod",
"companyId": "…",
"isActive": true,
"createdAt": "2026-01-01T00:00:00.000Z"
}
| Field | Description |
|---|---|
id | Service provider identifier. |
apiKey | The SP's API key. |
apiSecretPrimary | The primary API secret. Returned only once at creation. |
oauthUser / oauthPasswordPrimary | OAuth credentials. The password is returned only once. |
isActive | Whether the SP is active and usable immediately (see below). |
Store the credentials now.
apiSecretPrimaryandoauthPasswordPrimaryare shown only in this response and cannot be retrieved later. If you lose them, use the reset endpoint (section 3.2).
Production activation: A prod service provider is created inactive
(isActive: false) and must be activated by iProov before it can be used.
dev and test SPs are active immediately. (Admin companies receive active
prod SPs automatically.)
Errors
| Status | Internal code | When |
|---|---|---|
400 | 104000 | Missing/invalid fields (e.g. bad environment). |
403 | 104031 | Your company's SP Creation API access has been revoked. |
403 | 104030 | Your company is not approved to create service providers. |
409 | 104090 | An SP with that name already exists for your company. |
502 | 105020 | Upstream error creating the SP. Retry later. |
3.2 Reset a service provider credential
Rotate one of an SP's credentials. The SP must belong to your company.
POST /service-providers/{apiKey}/reset
Path parameter
| Parameter | Description |
|---|---|
apiKey | The API key of the SP to update. |
Request body
| Field | Type | Required | Allowed values |
|---|---|---|---|
credential | string | yes | secret, oauth |
tier | string | yes | primary, secondary |
cluster | string | yes | The cluster identifier of the SP. |
Why is
clusterrequired? An API key is only unique per cluster — if an SP has been copied to another cluster it keeps the sameapiKey. Supplying the cluster guarantees the reset targets exactly the SP you intend.
{
"credential": "secret",
"tier": "primary",
"cluster": "beta.rp.secure.iproov.me"
}
Understanding tier — the two credential slots
Every service provider holds two independent, simultaneously-valid copies of
each credential. tier selects which copy you are rotating:
credential | tier: "primary" | tier: "secondary" |
|---|---|---|
secret | apiSecretPrimary | apiSecretSecondary |
oauth | oauthPasswordPrimary | oauthPasswordSecondary |
Both tiers authenticate equally — the SP accepts either at any time. This is what makes zero-downtime rotation possible: because there are always two live values, you can replace one while the other keeps serving traffic, so the SP is never left without a working credential.
Recommended rotation flow (no downtime):
- Your system is authenticating with the primary credential.
- Reset the secondary tier, deploy the returned value, and switch your traffic over to it.
- Once everything is using the secondary, reset the primary tier to retire the old value.
Next time you rotate, do the same in reverse (retire secondary first, etc.). A single reset only ever changes the one slot you name — the other tier is untouched and keeps working throughout.
The same rotation is available to portal admins in the iPortal UI (the service provider's Secrets screen), which exposes the primary and secondary slots for both credentials. The UI and this API target the same two slots, so a value rotated one way is honoured by the other.
Response — 200 OK
Only the field matching the credential and tier you reset is returned;
the others are omitted. The field name combines the two:
| Request | Field returned |
|---|---|
credential: "secret", tier: "primary" | apiSecretPrimary |
credential: "secret", tier: "secondary" | apiSecretSecondary |
credential: "oauth", tier: "primary" | oauthPasswordPrimary |
credential: "oauth", tier: "secondary" | oauthPasswordSecondary |
For example, resetting the primary API secret returns:
{
"apiSecretPrimary": "…"
}
The new value is returned only once. Store it immediately.
Errors
| Status | Internal code | When |
|---|---|---|
400 | 104000 | Invalid credential or tier, or missing cluster. |
403 | 104030 | The SP belongs to a different company. |
404 | 104040 | No SP found for that apiKey on that cluster. |
4. Error format
Every error response has the same shape:
{
"error_description": "Forbidden",
"internal_code": 104030,
"status_code": 403
}
| Field | Description |
|---|---|
error_description | Human-readable summary. |
internal_code | Stable machine-readable code (see table below). |
status_code | HTTP status, mirrored in the body. |
Internal codes
| Code | HTTP | Meaning |
|---|---|---|
104000 | 400 | Validation error — check the request fields. |
104010 | 401 | Unauthorized — missing/invalid authentication. |
104011 | 401 | Invalid service account credentials (or inactive account). |
104030 | 403 | Forbidden — insufficient permissions or company not approved. |
104031 | 403 | Your company does not have SP Creation API access. |
104040 | 404 | Resource not found. |
104041 | 404 | Service account not found (iPortal management only). |
104090 | 409 | Conflict — name already in use. |
105000 | 500 | Unexpected server error. |
105020 | 502 | Error communicating with an upstream service. Retry later. |
5. Health endpoints
Unauthenticated probes for monitoring:
| Endpoint | Response |
|---|---|
GET /status | { "status": "okay", "service": "iportal-public-api" } |
GET /ready | { "status": "ready" } |
Quick start
# 1. Exchange service account credentials for a token
TOKEN=$(curl -s -X POST https://<host>/management/auth/token \
-u "$SERVICE_ACCOUNT_KEY:$SECRET" | jq -r .jwt)
# 2. Create a service provider
curl -s -X POST https://<host>/management/service-providers \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name":"Onboarding SP","environment":"dev","cluster":"beta.rp.secure.iproov.me"}'