payout / developers
API reference

PayoutID API

Payout OIDC, OAuth2 and verification server.

  • OAuth2: redirect users to PayoutID for authorization, then exchange the result for an access token. Tokens can also be refreshed or issued to your own client with client credentials.
  • Verifications: create identity verification invitations for your customers and receive the results by webhook.

Guides: OAuth2 and identity verification.

Authentication

Payout registers your application as a PayoutID client and gives you a client_id (a UUID) and a client_secret. The client also has its registered redirect URIs and the scopes it may request.

Token endpoint. Authenticate your client at POST /oauth/token in one of these ways:

  • client_secret_basic: HTTP Basic authentication with client_id as the user name and client_secret as the password.
  • client_secret_post: client_secret as a body parameter.

Both are enabled for every client by default. Always send client_id in the body as well. Clients that Payout configured for client_secret_jwt or private_key_jwt send a signed JWT in client_assertion instead of the secret.

Verifications API. Send the access token returned by the token endpoint in the Authorization header:

Code
Authorization: Bearer <access_token>

Access tokens are JWTs signed by PayoutID. A token works only in the environment that issued it: https://id-sa.payout.one for Sandbox, https://id.payout.one for Production.

Errors

Token endpoint. Errors are JSON objects with error and error_description:

JSON
{
  "error": "invalid_grant",
  "error_description": "Given authorization code is invalid, revoked, or expired."
}
Status error Meaning
400 invalid_request A parameter is missing or malformed, or the PKCE code verifier is wrong
400 invalid_grant The authorization code or refresh token is invalid, revoked or expired
400 invalid_scope A requested scope is not enabled for your client or not allowed for this grant
400 unsupported_grant_type The grant type is not enabled for your client
401 invalid_client Unknown client, wrong client secret or redirect URI that does not match
500 unknown_error Unexpected server error

Authorization redirect. Errors are sent to your redirect_uri as the error, error_description and state query parameters. If the user denies access, you get error=access_denied. If client_id or redirect_uri is invalid, PayoutID cannot redirect back safely and shows an error page to the user.

Verifications API.

Status Body Meaning
403 Plain text UNAUTHORIZED: Missing or insuficient authorization The token is missing, invalid or expired, or it lacks the verify scope
422 {"errors": {"<field>": ["<message>"]}} Validation failed
GET

Authorization redirect for user

/oauth/authorize

Endpoint where client should redirect user for authorization.

Open this URL in the user's browser; it is not an API call. PayoutID asks the user to log in or register if needed, then to approve the requested scopes. Afterwards it redirects the browser back to redirect_uri:

  • on success, with code (the authorization code) and state;
  • on error or when the user denies access, with error, error_description (when available) and state.

The authorization code is valid for at most 60 seconds and can be used once. Exchange it at POST /oauth/token with grant_type=authorization_code.

Parameters

client_id requiredquery · string<uuid>
Client ID of application that is trying to authorize user · e.g. c24760a3-134f-4ff5-891b-e506a025a530
response_type requiredquery · string
Must be code (authorization code flow). one of code
redirect_uri requiredquery · string
Redirect uri that was registered for this client · e.g. https://www.example.com
scopequery · string
Space-separated scopes to authorize. Each scope must be enabled for your client. e.g. openid profile
code_challengequery · string
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier))), see RFC 7636 https://tools.ietf.org/html/rfc7636. Required when PKCE is enabled for your client. e.g. E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
code_challenge_methodquery · string
Code challenge method. Use S256; plain is also accepted. one of S256, plain · e.g. S256
statequery · string
This parameter is sent back in the redirect url to identify request/response pairs · e.g. c0416c89-02fb-4c64-b4f6-9ebee510f4a0

Responses

302
Redirects the browser to the PayoutID login and consent pages, and finally back to redirect_uri with the authorization response.
Request
curl -X GET 'https://id-sa.payout.one/oauth/authorize?client_id=c24760a3-134f-4ff5-891b-e506a025a530&response_type=code&redirect_uri=https://www.example.com'
POST

Endpoint to retrieve authorization token

/oauth/token

Endpoint where client can retrieve authorization token after successful authorization, refresh an expired access token with a valid refresh token, or get a token for itself with client credentials.

grant_type Use Parameters
authorization_code Exchange the code from the authorization redirect code, redirect_uri; code_verifier when PKCE is enabled for your client
refresh_token Get a new access token for the same user and client refresh_token; optional scope
client_credentials Get a token for your own client, without a user. The Verifications API needs scope verify. optional scope

Every grant needs client_id in the body. The client secret (HTTP Basic or client_secret in the body) is required for client_credentials, for refresh_token unless public refresh is enabled for your client, and for authorization_code when your client is confidential.

A refresh revokes the refresh token that was used, and the response carries a new one. id_token is returned by the authorization_code grant when the openid scope was granted. Scopes that only a user can grant, such as PISPSUBMIT, cannot be requested with client_credentials.

The body can be sent as application/x-www-form-urlencoded or as JSON.

Request body

grant_type requiredstring
Grant type. one of authorization_code, refresh_token, client_credentials
client_id requiredstring<uuid>
Client ID. Send it in the body even when you authenticate with HTTP Basic. e.g. c24760a3-134f-4ff5-891b-e506a025a530
client_secretstring
Client secret (client_secret_post). Omit it when you authenticate with HTTP Basic.
codestring
authorization_code: the code from the authorization redirect. e.g. 63a74bf4-fa3d-4b21-8350-8c51ae47d74a
redirect_uristring
authorization_code: the same redirect_uri that was used in the authorization request. e.g. https://www.example.com
code_verifierstring
authorization_code: PKCE code verifier. Required when PKCE is enabled for your client. e.g. dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk
refresh_tokenstring
refresh_token: refresh token from a previous token response. e.g. 4b217f27-836a-4a12-97a3-b962c23dedc5
scopestring
Space-separated scopes. client_credentials: each scope must be enabled for your client. refresh_token: optional, at most the scopes of the original token, which are used when omitted. e.g. verify account_info
client_assertion_typestring
Only for clients configured for client_secret_jwt or private_key_jwt. one of urn:ietf:params:oauth:client-assertion-type:jwt-bearer
client_assertionstring
Only for clients configured for client_secret_jwt or private_key_jwt. Signed JWT with sub set to your client ID, aud set to the PayoutID URL of the environment, and iss and exp claims.

Response 200

access_tokenstring
Access token (JWT). Send it as Authorization: Bearer <access_token>.
token_typestring
Token type. one of bearer
expires_ininteger
Seconds until the access token expires. e.g. 86400
refresh_tokenstring
Refresh token for the refresh_token grant.
id_tokenstring
OpenID Connect ID token (JWT). Returned by the authorization_code grant when the openid scope was granted.

Other responses

400
Invalid request, grant or scope, or a grant type the client does not support
401
Client authentication failed
Request
curl -X POST 'https://id-sa.payout.one/oauth/token' \
  -u "$CLIENT_ID:$CLIENT_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
       "grant_type": "authorization_code",
       "client_id": "c24760a3-134f-4ff5-891b-e506a025a530",
       "code": "63a74bf4-fa3d-4b21-8350-8c51ae47d74a",
       "redirect_uri": "https://www.example.com",
       "code_verifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
     }'
Response 200
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6ImF0K2p3dCJ9.eyJpc3MiOiJodHRwczovL2lkLXNhLnBheW91dC5vbmUifQ.…",
  "token_type": "bearer",
  "expires_in": 86400,
  "refresh_token": "4b217f27-836a-4a12-97a3-b962c23dedc5"
}
POST

Create invitation

/v1/verification/invitation

Invitation to identity verification

Creates URL to which you can redirect customer to get him verified.

Use an access token from the client_credentials grant with scope verify. Add scope account_info to request bank account details (bank_account_requested) and scope aml to request an AML check (aml_requested).

When all data are retrieved, PayoutID sends the user details as a webhook to notify_url, and AML check results to aml_notify_url. The identity verification guide describes the webhooks and how to verify their signatures.

Request body

provided_emailstring<email>
Customer email, prefilled in the verification. max 160 · e.g. john.doe@example.com
provided_namestring
Customer first name, prefilled in the verification. e.g. John
provided_surnamestring
Customer last name, prefilled in the verification. e.g. Doe
bank_account_requestedboolean
Indicates if bank account details will be present in the webhook. Requires scope account_info. default false
aml_requestedboolean
Indicates if AML check is requested. Requires scope aml and aml_notify_url. default false
client_provided_ibanstring
If client requires to verify concrete IBAN, not any IBAN that customer have access to. Must be a valid IBAN of a supported Slovak or Czech bank. e.g. CZ6508000000192000145399
callback_url requiredstring
The URL to which customer will be redirected after completing required steps to start verification. e.g. https://example.com
notify_url requiredstring
Where webhook with user details will be sent when all data are retrieved. e.g. https://example.com/webhooks/payout-id
aml_notify_urlstring
Where webhook with AML check details will be sent. Required if aml_requested is true. e.g. https://example.com/webhooks/payout-id-aml

Response 200

idstring<uuid>
The unique identifier for the verification process.
redirect_urlstring
The URL to redirect to for the verification process.

Other responses

403
The access token is missing, invalid or expired, or it lacks the verify scope. The body is plain text.
422
Validation failed, for example an invalid IBAN, a missing required field, or bank_account_requested / aml_requested without the matching scope (missing scope for condition).
Request
curl -X POST 'https://id-sa.payout.one/api/v1/verification/invitation' \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
       "client_provided_iban": "CZ6508000000192000145399",
       "bank_account_requested": true,
       "callback_url": "https://example.com",
       "notify_url": "https://example.com/webhooks/payout-id"
     }'
Response 200
{
  "id": "f2a060df-4812-4335-8706-1c29e61c8b47",
  "redirect_url": "https://id-sa.payout.one/verifications/f2a060df-4812-4335-8706-1c29e61c8b47"
}

Was this page helpful?