OAuth 2.0 / OpenID Connect
e-Próspera provides an OAuth 2.0 and OpenID Connect authorization server so third-party applications can authenticate users and access their data with consent.
Capabilities
- Authenticate users with their e-Próspera account
- Receive standard OIDC claims (
sub,name,email,picture) - Obtain refresh tokens for long-lived server access via
offline_access - Fetch user-authorized personal and legal-entity data through the
/api/v1/me/*endpoints - Read personal or consented-entity tax obligations and submitted filings
Getting credentials
OAuth clients are provisioned per account. If you already have one, you can view the client ID, allowed scopes, and redirect URIs in Developer → OAuth application.
To request a new client or have your secret re-issued, use the e-Próspera Help Center chat.
Redirect URI requirements
Register every callback URI in full, including its scheme, host, port, path, and query string. Authorization requests use exact string matching: a URI that differs only by host capitalization, an explicit default port, or a trailing slash is still a different URI.
- Production callbacks must use HTTPS.
- Staging and local-development clients may use HTTP only with
127.0.0.1,[::1], orlocalhost. - Prefer
127.0.0.1or[::1]for new local integrations.localhostremains supported for compatibility. - Credentials, fragments, and raw semicolons are not permitted.
- Ports are matched exactly.
Testing a callback locally
Use a separately provisioned staging OAuth client and register the exact
loopback callback your local application listens on, for example
http://127.0.0.1:3001/auth/oauth2/callback/prospera. Start the flow through
https://staging-portal.eprospera.com; the production authorization server
rejects HTTP callbacks, including loopback addresses. See Testing in
staging for the complete setup.
Older stored callbacks may remain visible while you edit a client. They can be removed, but they are not automatically rewritten and cannot be duplicated if they no longer satisfy the current registration policy. A grandfathered HTTP callback is never accepted by the production authorization endpoint.
Standard endpoints
| Endpoint | URL |
|---|---|
| OpenID configuration | https://portal.eprospera.com/.well-known/openid-configuration |
| JWKS | https://portal.eprospera.com/api/oauth/.well-known/jwks.json |
| Authorization endpoint | https://portal.eprospera.com/api/oauth/authorize |
| Device endpoint | https://portal.eprospera.com/api/oauth/device_authorization |
| Token endpoint | https://portal.eprospera.com/api/oauth/token |
| UserInfo endpoint | https://portal.eprospera.com/api/oauth/userinfo |
| Revocation endpoint | https://portal.eprospera.com/api/oauth/revoke |
| Introspection endpoint | https://portal.eprospera.com/api/oauth/introspect |
Reference pages:
- OpenID configuration
- JWKS
- Authorization endpoint
- Device authorization endpoint
- Token endpoint
- UserInfo endpoint (GET)
- UserInfo endpoint (POST)
- Revocation endpoint
- Introspection endpoint
Recommended initial scopes
Start with:
openid profile emailAdd offline_access if your backend needs refresh tokens.
Supported scopes
| Scope | Description |
|---|---|
openid | Authenticate the user with e-Próspera. |
profile | Read the user's name and profile picture. |
email | Read the user's email address. |
offline_access | Receive a refresh token for background access-token renewal. |
eprospera:person.details.read | Read detailed natural-person profile data. |
eprospera:person.residency.read | Read the user's current residency status. |
eprospera:person.id_verification.read | Read the latest approved identity-verification images. |
eprospera:entity.read | Read legal-entity data for entities the user consents to share. |
eprospera:entity.documents.read | Read legal-entity documents for consented entities. |
eprospera:person.tax.read | Read the user's tax obligations and submitted filings. |
eprospera:entity.tax.read | Read tax data for consented legal entities. |
Consent behavior
When you request entity scopes (eprospera:entity.read,
eprospera:entity.documents.read, or eprospera:entity.tax.read), the consent
screen lets the user choose which legal entities to share. The access token is
limited to that selection.
This means:
GET /api/v1/me/legal-entitiescan return an empty array even with a valid token.GET /api/v1/me/legal-entities/{id}and/documentsonly work for consented entity IDs.- If the user is no longer a representative of an entity, it stops appearing in responses.
Remembered consent
Once a user approves your client, the grant is remembered. Later authorization requests covered by the remembered grant skip the consent screen — the user is redirected straight back to your redirect_uri with a fresh authorization code. Requests for additional scopes show the consent screen again, and you can always force it with prompt=consent.
Revocation from Connected apps
Users can revoke your app's access at any time from portal Settings → Connected apps. Revocation invalidates all of your tokens for that user: access tokens stop working, and refresh attempts fail with invalid_grant. Handle invalid_grant by sending the user back through the authorization flow.
PKCE
All newly registered clients must use PKCE: send code_challenge + code_challenge_method=S256 on the authorization request and the matching code_verifier on the token exchange. Authorization requests from PKCE-required clients without a code challenge fail with error=invalid_request. Existing clients without the flag should adopt PKCE too — it is strongly recommended for every integration.
Client secret rotation
You can request a rotation of your client secret at any time through the e-Próspera Help Center chat. After a rotation, the old secret keeps working during a grace period so you can deploy without downtime — update your integration to the new secret before the grace period expires.
Resource endpoints
For an end-to-end explanation of user and entity selection, CLI examples, and sensitive-data handling, see Tax and legal-entity data.
The scopes above unlock these endpoints:
| Endpoint | Required scope |
|---|---|
GET /api/v1/me/natural-person | eprospera:person.details.read |
GET /api/v1/me/natural-person/residency | eprospera:person.residency.read |
GET /api/v1/me/natural-person/id-verification | eprospera:person.id_verification.read |
GET /api/v1/me/legal-entities | eprospera:entity.read |
GET /api/v1/me/legal-entities/{id} | eprospera:entity.read |
GET /api/v1/me/legal-entities/{id}/documents | eprospera:entity.documents.read |
GET /api/v1/me/tax/summary | personal or entity tax read |
GET /api/v1/me/tax/filings | personal or entity tax read |
GET /api/v1/me/tax/filings/{filingId} | personal or entity tax read |
GET /api/v1/me/tax/filings/{filingId}/documents/{document} | personal or entity tax read |
/api/v1/me/natural-person/id_verification (underscore) exists as a
compatibility alias. Use /id-verification (hyphen) for new integrations.
Authorization flow
response_type=codeis required.stateis required.nonceis required whenopenidis in scope.response_modeis optional (query,fragment, orform_post; defaultquery).prompt,max_age, andlogin_hintare supported — see the authorization endpoint reference.- Every authorization response includes the
issparameter (RFC 9207); validate it againsthttps://portal.eprospera.com. - Unauthenticated users are redirected to the portal login before returning to the authorization request.
- Repeat the registered
redirect_uriexactly during the authorization-code exchange.
Client authentication and request encoding
Send token, revocation, and introspection requests as
application/x-www-form-urlencoded. HTTP Basic authentication is recommended:
curl -X POST https://portal.eprospera.com/api/oauth/token \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=authorization_code" \
-d "code=$CODE" \
-d "redirect_uri=$REDIRECT_URI" \
-d "code_verifier=$CODE_VERIFIER"client_secret_post remains available for compatibility. Do not combine Basic
authentication with body credentials, and do not repeat OAuth parameters.
The official CLI is a registered public client. Its device-token and revocation requests send the client ID without a client secret. This secretless public-client mode is reserved for the official CLI; third-party clients should use their provisioned authentication method and the authorization-code flow with PKCE.
Device authorization for the official CLI
The official eprospera CLI is a public OAuth client and uses the device flow,
so it never embeds a client secret. Start it with:
eprospera auth login --oauthThe CLI displays a short code and opens the portal consent page. It polls the
token endpoint at the server-provided interval, handles authorization_pending
and slow_down, and stores the resulting rotating refresh token securely. This
flow is currently reserved for the official CLI; third-party OAuth clients use
the authorization-code flow with PKCE.
Refresh tokens
Access tokens expire after 1 hour.
If the granted scope set includes offline_access, the token response also includes a refresh_token valid for up to 180 days.
Example refresh request:
curl -X POST https://portal.eprospera.com/api/oauth/token \
-u "$CLIENT_ID:$CLIENT_SECRET" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=refresh_token" \
-d "refresh_token=$REFRESH_TOKEN"Refresh tokens rotate on every successful refresh. Always persist the newest
refresh_token from the response. You may request a reduced scope set on
refresh, provided it is a subset of the originally granted scopes. When
openid is granted, the refresh response also includes a fresh id_token
whose auth_time remains the time of the user's original authentication.
Reusing an already rotated refresh token revokes its token family; restart the
authorization flow after invalid_grant.
Bearer-token errors
Protected endpoints return a WWW-Authenticate: Bearer challenge for missing
or invalid access tokens. A valid token without the required scope returns
403 with error="insufficient_scope". The UserInfo endpoint supports both
GET and POST.
Framework guides
Register event visitors with zero credentials
Submit visitor-pass applications from your event site, coworking space, or tourism platform — no API key required.
Tax and legal-entity data
Use OAuth or the official CLI to read your own tax records and data for legal entities you actively represent and explicitly consent to share.