ISECure WS Channel API API Reference

The API provides secure file exchange with common banks in Finland via the SEPA WebServices channel, including certificate enrollment (PKI) and automatic certificate renewals.

The OpenAPI v2 specification is published on GitHub isecurefi/wsapi-v2. Browser-compatible TypeScript SDK is available on GitHub dforsber/isecure-ts-client. Command line CLI and PHP SDK remain available on GitHub isecurefi/wscli-php.

import { WSChannel } from "isecure-ts-client";

const client = new WSChannel({
  ApiKey: process.env.ISECURE_API_KEY ?? "0",
  Company: "Example Company Oy",
  Name: "Example User",
  Password: process.env.ISECURE_PASSWORD!,
  Phone: "+358401234567",
  PublicKey: process.env.ISECURE_PUBLIC_KEY_PEM!,
  BaseUrl: "https://ws-api.isecure.fi/v2",
  Email: "user@example.com",
  Mode: "data",
  Bank: "nordea",
});

const state = await client.login();
if (state.status === "authenticated") {
  const certs = await client.listCerts();
  console.log(certs.Certs);
}
export SESSION=~/.wscli/settings.yaml
wscli session login -c $SESSION
export APIKEY=$(yq -r .settings.apikey $SESSION)
export IDTOKEN=$(yq -r .settings.idtoken $SESSION)

curl -H Authorization:$IDTOKEN \
     -H x-api-key:$APIKEY \
     https://ws-api.isecure.fi/v2/files/danskebank

The API provides role based access control (RBAC), user account management, password recovery, and SMS or authenticator-app (TOTP) multi-factor authentication based on Amazon Cognito user pools.

NOTE: The API endpoint for production is the same as for test, but without test. in the URL. Production and test APIs are deployed on separate AWS accounts.

NOTE: The API runs on AWS API Gateway with AWS Lambda backends. Cold Lambda functions can add a small response delay. Banks can also have considerable processing delays, especially for certificate enrollments.

Service enrollment

Every integrator (partner) has an own API Key, and every user account belongs to one integrator. The API Key is bound to the service subscription. In other words, a new production API Key requires a service agreement before file transfers are allowed.

If a user registers with 0 as the API Key, the API creates a new API Key and the user becomes the API Key owner. The owner account can list all users under the same API Key with the Integrator API. Integrators register their own owner account first and use its API key to register customer accounts.

NOTE: API call rate limits are set and tracked per API Key by AWS API Gateway.

Account management

A user email address can have an admin account, a data account, or both. The role in the API is called mode. The modes have separate passwords and different capabilities.

Login always requires both email address and mode. Admin mode login always requires MFA. Existing accounts may continue with SMS MFA, and accounts that have enrolled software-token MFA use authenticator-app/TOTP codes. Data mode uses password authentication and is suitable for automation. Admin mode configures the account, such as PGP keys and certificate sharing. Data mode exchanges files. Listing files is allowed in both modes.

NOTE: Integrators register customer accounts by using the API key from the API key owner account.

Initial registration with TOTP

  1. Register the admin account first. Use InitRegister to get the challenge and Register to create the account.
  2. Login with admin mode. Complete the returned SMS MFA challenge with LoginMFA.
  3. Confirm phone with VerifyPhone and email with VerifyEmail when required. After verification, start a fresh login cycle.
  4. During an authenticated admin SMS MFA login, call LoginMFA with SetupTOTP: true. The response includes SecretCode, OtpauthUri, and an in-memory AccessToken.
  5. Show OtpauthUri as a QR code, or let the user enter SecretCode manually in an authenticator app.
  6. Submit the authenticator code and the returned AccessToken to VerifyTOTP. TOTP becomes the preferred admin MFA method; SMS remains available as a fallback.
  7. Register the data account with the same email and API key for automation/file transfer workflows.
const registration = await adminClient.register();
let state = await adminClient.login();

if (state.status === "needs_mfa" && state.method === "sms") {
  state = await adminClient.submitMfaCode(smsCode, { setupTotp: true });
}

if (state.status === "authenticated" && state.totpEnrollment) {
  const { otpauthUri, secret, accessToken } = state.totpEnrollment;
  // Render otpauthUri as a QR code, or display secret for manual entry.
  await adminClient.verifyTotp(accessToken, codeFromAuthenticatorApp);
}

Existing SMS MFA user migration to TOTP

  1. Login with the existing admin account.
  2. When Login returns ChallengeName: SMS_MFA, submit the SMS code with LoginMFA and set SetupTOTP: true.
  3. Add the returned OtpauthUri or SecretCode to the authenticator app.
  4. Confirm enrollment with VerifyTOTP using the returned AccessToken and the current authenticator code.
  5. Future admin logins normally return ChallengeName: SOFTWARE_TOKEN_MFA; submit the authenticator code through LoginMFA. SMS remains available as a fallback for accounts where Cognito still has SMS MFA enabled.
let state = await adminClient.login();
if (state.status === "needs_mfa" && state.method === "sms") {
  state = await adminClient.submitMfaCode(smsCode, { setupTotp: true });
}
if (state.status === "authenticated" && state.totpEnrollment) {
  await adminClient.verifyTotp(state.totpEnrollment.accessToken, authenticatorCode);
}

Bank certificate enrollment

The SEPA WebServices connection to the bank requires enrolling a PKI certificate with the bank. Admin mode can enroll certificates for different banks, but only one certificate per bank. The corresponding private key is generated and stored encrypted with AWS KMS.

Bank certificate sharing

It is possible to share the same bank certificate with multiple accounts. Certificate sharing can be configured when accounts have the same API key. The account that holds the certificate can share it with another account ( admin mode operation). Only the account that owns the certificate can PGP-export the certificate and corresponding private key. This allows one admin mode account to own certificates and share them with multiple data mode accounts.

An account can never have multiple certificates per bank, whether shared or directly enrolled. The API identifies the bank, not an individual certificate/key pair.

Access security

Access is secured with TLS on AWS API Gateway. Inside TLS, register and login use challenge-response: the client fetches fresh username-specific parameters with InitRegister or InitLogin, RSA-encrypts the password and challenge timestamp with OAEP padding, and submits the encrypted value to Register, Login, or PasswordReset.

Successful login returns a Cognito IdToken and the integrator ApiKey. For protected operations, send Authorization: <IdToken> and x-api-key: <ApiKey>. The OpenAPI document also models these headers as security schemes. If a generated client exposes both explicit header parameters and security settings, use the same values for both; the wire request must contain exactly those two headers.

Administrative actions require MFA authentication. SMS MFA remains available and TOTP can be enrolled with LoginMFA and confirmed with VerifyTOTP. User account management is handled with Cognito user pools. Each email can have separate admin and/or data mode Cognito users that share the same API account data.

Error handling and retryability

Successful logical API responses have ResponseCode: "00". Logical failures usually return ResponseCode: "01" with a human-readable ResponseText and RequestId. Include RequestId in support tickets.

HTTP status still matters. 401/403 authentication and authorization failures are not retryable without changing credentials, token, role, API key, or verification state. Invalid API key is not retryable. Validation errors are not retryable without changing the request. Bank/backend integration errors may be retryable only when the text indicates a temporary upstream problem, timeout, throttling, or bank-side availability issue.

The TypeScript SDK throws typed transport errors for non-2xx responses and network failures, while API-level failures are returned as structured response objects or typed authentication states. Prefer the SDK for browser and Node.js integrations so MFA, retries, logging redaction, and session handling stay consistent. Browser clients use normal API methods through the TypeScript SDK. API Gateway also supports CORS preflight OPTIONS requests, but these are infrastructure-only and are not public API operations or SDK methods.

CHANGELOG

2.7.0 :: 2026-06-25

  • Added software-token/TOTP admin MFA (LoginMFA with SetupTOTP and VerifyTOTP) while keeping SMS MFA available.
  • Documented the browser-compatible TypeScript SDK.
  • Added browser CORS preflight support (OPTIONS) for the TypeScript SDK. OPTIONS is infrastructure-only and not a public SDK operation.

2.6.0 :: 2021-06-14

  • Added token revocation for logout (AWS SDK based new capability), no changes to the API itself.

2.5.0 :: 2020-04-19

  • Removed OPTIONS from the documented business API operations.
  • Fixed Login response.
API Endpoint
https://ws-api.isecure.fi/v2
Terms of Service: https://www.isecure.fi/ws-api-terms
Contact: dan.forsberg@isecure.fi
Schemes: https
Version: v2.7.0

Authentication

Authorizer

Successful login provides IdToken that must be provided in the Authorization header

in
header
name
Authorization
type
apiKey

X-Api-Key

Integrator specific API Key. For all integrator customers, the API key must be the same.

in
header
name
x-api-key
type
apiKey

Account

InitRegister

GET /account/{Email}/{Mode}

Before register (or login), client must fetch challenge from the API. Then on register (or login), the challenge must be passed along to the API (as response to the challenge). The challenge is always fresh for some period of time and the API validates it when passed with register (or login). The challenge has form of base64-string|timestamp|uuid. For example:\n\nezwXceQ63fV9oWTSJBAE2Zq1Cw5tBIJe+7+Rl8jrgbk=|1475429754114|4017bda8-0a15-4154-a8b7-88069b05cb4e\n\n NOTE: The call must contain the same email as used for registration itself.\n

Email: string
in path

Email address as the account username, e.g. user@example.com

Mode: string admin, data
in path

Administer account with admin mode, exchange files with data mode

Operation successfully processed. See response.

400 Bad Request

Request validation error

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "Challenge": "9Ty4zrnJGqNH0i1+I0OTKHjTs03Ymd4tBH70FTiYNhA=|1494962070679|2646b71b-9b51-4d11-bf5e-cca5617bcfde",
  "ResponseCode": "..",
  "ResponseText": ".."
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

VerifyEmail

POST /account/{Email}/{Mode}

Provide the Code received by email and the AccessToken received during login. The access token is only used to complete verification and should not be persisted.

NOTE: Phone and email verification bypass is an integrator-level policy option for deployments where the integrator has already verified those attributes. Contact ISECure support if this is required for your API key.

Account parameters

Email: string
in path

Email address as the account username, e.g. user@example.com

Mode: string admin, data
in path

Administer account with admin mode, exchange files with data mode

Request Content-Types: application/json
Request Example
{
  "AccessToken": "eyJraWQiO...CzzcdcdAdEzKIcJPR7Fda0A",
  "Code": "123456"
}
200 OK

Operation successfully processed. See response.

400 Bad Request

Request validation error

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

Register

PUT /account/{Email}/{Mode}

You need to register both admin and data accounts with the same email address. Both accounts share the same data, but are used for different purposes. Admin account must be registered first, then data account.\n\n Admin account is used to configure setup with Certs and Pgp operations, while the data account is used with Files operations only. Both accounts use Account and Session operations.\n\n Admin account always requires MFA during login. SMS MFA remains available, and TOTP can be enrolled after SMS bootstrap. Data account does not require MFA. Generally, the data account is considered read-only when no PGP keys are configured, since PGP Keys are used to verify file upload signatures and are thus required to successfully upload files with Files UploadFile operation.\n\nRegistrations are independent for both accounts, admin and data and both require phone number and email verifications.\n\nemail is the login username for both accounts and mode defines the selected "mode" for the login, i.e. admin or data.\n\nBefore registration client must fetch challenge from API (see Account InitRegister operation) and pass it back within the ChResp parameter.\n\nThe following parameters name, phone, and company are required and must be valid (phone, email) as they need to be confirmed before registration becomes successful and login possible.\n\nClient must RSA encrypt (OAEP padding) the password and the challenge timestamp as string in the form password||timestamp, base64 encode it and provide the resulting string as Encrypted parameter. The RSA encryption can be done e.g. for illustration purposes within command line with openssl rsautl:\n\necho -n Toddler_..123456789012345\\|\\|1475175151231 |\n\topenssl rsautl -oaep -encrypt -pubin -inkey test.pem |\n\tbase64\n\n\n\nThe test API's RSA public key is as follows:\n\n\n% cat test.pem\n-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkuSaoSZztGAIGDTY7Rff\npsBHJJT1k207UodOJbYFhHAq0lWJnvMPLl5Q1DUUZdTGtTdL8Dsaj/Bo2+gSykMM\nR5QiKewvQsLfvqjwOO8JDItnhJl0lUqcPpdQV4M/Ai3YNRjNcVy4a+pichqtSAWl\n9S1HV01MNeouk8PEr/zoUasmgfO3mz6N6XTUtF/tIi8K2kBOsLAtqltihFSd/zT8\nifYZE9cZTJ09lUs7kMz1wxFIsiegaE1jUYV+VSLu3PJ97oKhQpqop8EnkBAoBl6r\nmdmFryBQIdakPIdd4rO5Yg+to10n4u7Wij9ePIwWMfbqY4QoW5nXqMgFJQkIt4TG\neQIDAQAB\n-----END PUBLIC KEY-----\n\n\nThe production API's RSA public key is as follows:\n\n\n% cat prod.pem\n-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7wx4l7P3eLsaEyK7ZRME\ng5urEHwaEoY9LjkYcpMw9gmPIi3RoGjQX7HzPad2D7ES2yIGdmyxjN8R2LyFa8ke\nEE+VY3ISYzP2cOjd/zDkX01yjDXQLRxntXbtqIypGQAzmZbCyIB226ZKEE+ldh6M\nYyM41YWYikfocYssFEjY7fpPGeUg4FOmHmyWIZeMkXYovskoi1jZ1Ay1qn95XlpA\n/Ptru2efro4T1xksv4WBBrj8bMNwdDpf4oyzH2PKYkn3/KlNTBCHlAmzP0jd4pIa\nN0tAf2m8TcNq7kuBzyfs8AcCUj870p8SEiko0PMx6K+zVsTVWsxfUX+/+kmapmp/\nAwIDAQAB\n-----END PUBLIC KEY-----\n\n\n\n\n NOTE: Password must be at least 20 characters long, have lower and upper case letters, numbers, and special characters.\n\n NOTE: Phone number must be provided with country code, e.g. +358404982201.

Account parameters

Email: string
in path

Email address as the account username, e.g. user@example.com

Mode: string admin, data
in path

Administer account with admin mode, exchange files with data mode

Request Content-Types: application/json
Request Example
{
  "ApiKey": "hzYAVO9Sg98nsNh81M84O2kyXVy6K1xwHD8",
  "ChResp": "ezwXceQ63fV9oWTSJBAE2Zq1Cw5tBIJe+7+Rl8jrgbk=|1475429754114|4017bda8-0a15-4154-a8b7-88069b05cb4e",
  "Company": "ISECure Oy",
  "Encrypted": "...",
  "Name": "Dan Forsberg",
  "Phone": "+358404835507"
}
201 Created

Operation successfully processed. Resource created. See response.

400 Bad Request

Request validation error

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (201 Created)
{
  "ApiKey": "4vN6hGHrav31smM0Ha1k15MDlZKOEGn43UToWTt2",
  "ResponseCode": "..",
  "ResponseText": ".."
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

InitPasswordReset

GET /account/{Email}/{Mode}/password

Start password reset for the selected email and mode. Cognito sends a confirmation code to the configured recovery channel. This flow is separate from admin login MFA.

Email: string
in path

Email address as the account username, e.g. user@example.com

Mode: string admin, data
in path

Administer account with admin mode, exchange files with data mode

200 OK

Operation successfully processed. See response.

400 Bad Request

Request validation error

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

PasswordReset

POST /account/{Email}/{Mode}/password

Set a new password for the selected email and mode. Provide the confirmation Code from the password reset flow.

NOTE: The new password must be RSA encrypted with the challenge timestamp; see Register for encryption details.

Account parameters

Email: string
in path

Email address as the account username, e.g. user@example.com

Mode: string admin, data
in path

Administer account with admin mode, exchange files with data mode

Request Content-Types: application/json
Request Example
{
  "ChResp": "ezwXceQ63fV9oWTSJBAE2Zq1Cw5tBIJe+7+Rl8jrgbk=|1475429754114|4017bda8-0a15-4154-a8b7-88069b05cb4e",
  "Code": "123456",
  "Encrypted": "..."
}
200 OK

Operation successfully processed. See response.

400 Bad Request

Request validation error

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

VerifyPhone

POST /account/{Email}/{Mode}/{Phone}

Confirm the phone number for the Email and Mode user with the Code received by SMS.

NOTE: Phone and email verification bypass is an integrator-level policy option for deployments where the integrator has already verified those attributes. Contact ISECure support if this is required for your API key.

Account parameters

Email: string
in path

Email address as the account username, e.g. user@example.com

Mode: string admin, data
in path

Administer account with admin mode, exchange files with data mode

Phone: string
in path

Phone number with country code, e.g. +358401234567

Request Content-Types: application/json
Request Example
{
  "Code": "123456"
}
200 OK

Operation successfully processed. See response.

400 Bad Request

Request validation error

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

Certs

ListCerts

GET /certs

List bank certificates visible to the authenticated account. The result includes certificates directly owned by the account and certificates shared to it by another account under the same API key.

Authorization: string
in header

Use IdToken from the Login response as the Authorization header

x-api-key: string
in header

Use ApiKey from the Login response as the x-api-key header

200 OK

Operation successfully processed. See response.

400 Bad Request

Request validation error

401 Unauthorized

Unauthorized

403 Forbidden

Unauthenticated

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "Certs": [],
  "ResponseCode": "..",
  "ResponseText": ".."
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (401 Unauthorized)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (403 Forbidden)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

ConfigCerts

POST /certs

Reserved admin operation for configuring certificate usage parameters such as private-key export policy. The current deployed implementation validates authorization and then returns configcerts not yet implemented; do not build production workflows that depend on this operation changing account state yet.

Certs handling settings

Authorization: string
in header

Use IdToken from the Login response as the Authorization header

x-api-key: string
in header

Use ApiKey from the Login response as the x-api-key header

Request Content-Types: application/json
Request Example
{
  "Export": "disabled"
}
200 OK

Operation successfully processed. See response.

400 Bad Request

Request validation error

401 Unauthorized

Unauthorized

403 Forbidden

Unauthenticated

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (401 Unauthorized)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (403 Forbidden)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

UnshareCerts

DELETE /certs/shared/{ExtEmail}

Reserved admin operation for removing certificate sharing from an existing ExtEmail account under the same API key. The current deployed implementation validates authorization and then returns unlinkaccount not yet implemented; contact ISECure support if certificate sharing must be removed before this operation is fully available.

Authorization: string
in header

Use IdToken from the Login response as the Authorization header

x-api-key: string
in header

Use ApiKey from the Login response as the x-api-key header

ExtEmail: string
in path

Unshare certs with ExtEMail account.

Operation successfully processed. See response.

400 Bad Request

Request validation error

401 Unauthorized

Unauthorized

403 Forbidden

Unauthenticated

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "ResponseCode": "..",
  "ResponseText": "..",
  "SharedFrom": [],
  "SharedTo": []
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (401 Unauthorized)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (403 Forbidden)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

ShareCerts

PUT /certs/shared/{ExtEmail}

Share this account's bank certificates with an existing ExtEmail account under the same API key. The caller must be authenticated in admin mode and must own the certificate being shared. The target account can then use the shared certificate for bank operations, but certificate/private-key export remains available only to the certificate owner.

Authorization: string
in header

Use IdToken from the Login response as the Authorization header

x-api-key: string
in header

Use ApiKey from the Login response as the x-api-key header

ExtEmail: string
in path

Share certs with ExtEMail account.

201 Created

Operation successfully processed. Resource created. See response.

400 Bad Request

Request validation error

401 Unauthorized

Unauthorized

403 Forbidden

Unauthenticated

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (201 Created)
{
  "ResponseCode": "..",
  "ResponseText": "..",
  "SharedFrom": [],
  "SharedTo": []
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (401 Unauthorized)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (403 Forbidden)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

ExportCert

GET /certs/{Bank}

Download bank certificate and private key encrypted with stored PGP key.\n\n NOTE: The previously uploaded PgpKeyId must have purpose type export. I.e. purpose type authorize PGP keys cannot be used for exporting.\n\n NOTE: If export has been set to disabled (see ConfigCerts), then exporting private keys is not possible through API.

Authorization: string
in header

Use IdToken from the Login response as the Authorization header

x-api-key: string
in header

Use ApiKey from the Login response as the x-api-key header

Bank: string
in path

Bank used for this operation, can have values of nordea, osuuspankki, danskebank, aktia, sp, shb, pop, spankki, or alandsbanken.

PgpKeyId: string
in query

Short version of a PGP Key id identifying the exported Private Key, e.g. 3A3A59B2

Operation successfully processed. See response.

400 Bad Request

Request validation error

401 Unauthorized

Unauthorized

403 Forbidden

Unauthenticated

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "CertsAndKeys": [],
  "ResponseCode": "..",
  "ResponseText": ".."
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (401 Unauthorized)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (403 Forbidden)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

EnrollCert

POST /certs/{Bank}

Provide WS-Channel user id, WsUserId, Company, and PIN Code for Bank certificate enrollment. Company must match with the contract with the bank and is part of enrollment process. Note that certificate private key is securely generated and stored encrypted with AWS KMS encrypted authentication on API side. Certificates are automatically renewed when needed.\n\n NOTE: For OP bank, ensure that you set the PIN code blocks 1 and 2 in correct order. If not initially in correct order, bank will lock the registration and you need to call them for unlock.

Certs parameters

Authorization: string
in header

Use IdToken from the Login response as the Authorization header

x-api-key: string
in header

Use ApiKey from the Login response as the x-api-key header

Bank: string
in path

Bank used for this operation, can have values of nordea, osuuspankki, danskebank, aktia, sp, shb, pop, spankki, or alandsbanken.

Request Content-Types: application/json
Request Example
{
  "Code": "8642603384107437",
  "Company": "ISECURE OY",
  "WsUserId": "..."
}
201 Created

Operation successfully processed. Resource created. See response.

400 Bad Request

Request validation error

401 Unauthorized

Unauthorized

403 Forbidden

Unauthenticated

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (201 Created)
{
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (401 Unauthorized)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (403 Forbidden)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

ImportCert

PUT /certs/{Bank}

Provide WsUserId, Company, PrivateKey, and Certificate for importing existing WS Channel certificate and private key. Company must match with the contract with the bank. Certificate(s) and private key(s) must be PEM formatted.\n\n NOTE: EncCertificate and EncPrivatekey are for DanskeBank only.

Certs parameters

Authorization: string
in header

Use IdToken from the Login response as the Authorization header

x-api-key: string
in header

Use ApiKey from the Login response as the x-api-key header

Bank: string
in path

Bank used for this operation, can have values of nordea, osuuspankki, danskebank, aktia, sp, shb, pop, spankki, or alandsbanken.

Request Content-Types: application/json
Request Example
{
  "Certificate": "...",
  "Company": "ISECURE OY",
  "EncCertificate": "...",
  "EncPrivatekey": "...",
  "PrivateKey": "...",
  "WsUserId": "..."
}
201 Created

Operation successfully processed. Resource created. See response.

400 Bad Request

Request validation error

401 Unauthorized

Unauthorized

403 Forbidden

Unauthenticated

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (201 Created)
{
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (401 Unauthorized)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (403 Forbidden)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

Files

ListFiles

GET /files/{Bank}

Ask the selected Bank to list downloadable files matching filters. Status can be e.g. NEW, ALL, or DLD. FileType is bank specific (ALL is not accepted); see the bank specification. Returns a list of FileDescriptors.

NOTE: Certificate must be enrolled before files can be listed, downloaded, or uploaded.

NOTE: Uploaded files do not show up in the bank file listing.

export SESSION=~/.wscli/settings.yaml
      wscli session login -c $SESSION
      
      curl -H Authorization:$(yq -r .settings.idtoken $SESSION) \
           -H x-api-key:$(yq -r .settings.apikey $SESSION) \
           https://ws-api.isecure.fi/v2/files/danskebank
      
Authorization: string
in header

Use IdToken from the Login response as the Authorization header

x-api-key: string
in header

Use ApiKey from the Login response as the x-api-key header

Bank: string
in path

Bank used for this operation, can have values of nordea, osuuspankki, danskebank, aktia, sp, shb, pop, spankki, alandsbanken or SEB.

Status: string
in query

Status of the file, e.g. ALL. NEW, DLD

FileType: string
in query

Bank specific FileType identifies the file type to be listed

200 OK

Operation successfully processed. See response.

400 Bad Request

Request validation error

401 Unauthorized

Unauthorized

403 Forbidden

Unauthenticated

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "FileDescriptors": [],
  "ResponseCode": "..",
  "ResponseText": ".."
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (401 Unauthorized)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (403 Forbidden)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

UploadFile

PUT /files/{Bank}

Uploads file to bank if PGP signature(s) are valid. FileContents is a string of Base64 encoded file contents. FileType is bank specific. Signature is detached PGP signature or concatenation of PGP detached signatures in ASCII armor format. PGP signatures are used for authorizing file uploads. Currently one valid PGP authorize registered key signature is enough. FileName is upload filename.\n\n NOTE: The uploaded files do not show up on the file listing from bank.\n\n\n% export SESSION=~/.wscli/settings.yaml\n% wscli session login -c $SESSION\n% export APIKEY=`yq -r .settings.apikey $SESSION`\n% export IDTOKEN=`yq -r .settings.idtoken $SESSION`\n%\n% curl -X PUT -H Content-Type:application/json \\ \n -H Authorization:$IDTOKEN \\ \n -H x-api-key:$APIKEY \\ \n -d @request-example.json \\ \n https://ws-api.isecure.fi/v2/files/danskebank\n\n\n

Files parameters

Authorization: string
in header

Use IdToken from the Login response as the Authorization header

x-api-key: string
in header

Use ApiKey from the Login response as the x-api-key header

Bank: string
in path

Bank used for this operation, can have values of nordea, osuuspankki, danskebank, aktia, sp, shb, pop, spankki, alandsbanken or SEB.

Request Content-Types: application/json
Request Example
{
  "FileContents": "...",
  "FileName": "testfile",
  "FileType": "KTL",
  "Signature": "string"
}
201 Created

Operation successfully processed. Resource created. See response.

400 Bad Request

Request validation error

401 Unauthorized

Unauthorized

403 Forbidden

Unauthenticated

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (201 Created)
{
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (401 Unauthorized)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (403 Forbidden)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

DeleteFile

DELETE /files/{Bank}/{FileType}/{FileReference}

Delete or mark as deleted a bank-side file identified by Bank, FileType, and FileReference. Use values returned by ListFiles. Bank support and final semantics are bank-specific.

Authorization: string
in header

Use IdToken from the Login response as the Authorization header

x-api-key: string
in header

Use ApiKey from the Login response as the x-api-key header

Bank: string
in path

Bank used for this operation, can have values of nordea, osuuspankki, danskebank, aktia, sp, shb, pop, spankki, alandsbanken or SEB.

FileType: string
in path

File reference id from list files

FileReference: string
in path

File reference id from list files

200 OK

Operation successfully processed. See response.

400 Bad Request

Request validation error

401 Unauthorized

Unauthorized

403 Forbidden

Unauthenticated

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (401 Unauthorized)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (403 Forbidden)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

DownloadFile

GET /files/{Bank}/{FileType}/{FileReference}

Download a bank file identified by Bank, FileType, and FileReference. The file reference is received from ListFiles. The response Content field contains the file content returned by the bank, typically Base64 encoded.

Authorization: string
in header

Use IdToken from the Login response as the Authorization header

x-api-key: string
in header

Use ApiKey from the Login response as the x-api-key header

Bank: string
in path

Bank used for this operation, can have values of nordea, osuuspankki, danskebank, aktia, sp, shb, pop, spankki, alandsbanken or SEB.

FileType: string
in path

File type from list files

FileReference: string
in path

File reference identifier from list files

Operation successfully processed. See response.

400 Bad Request

Request validation error

401 Unauthorized

Unauthorized

403 Forbidden

Unauthenticated

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "Content": "xxxxxxxx",
  "ResponseCode": "..",
  "ResponseText": ".."
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (401 Unauthorized)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (403 Forbidden)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

Integrator

ListAccounts

GET /integrator/accounts

List accounts registered under the authenticated integrator API key. This is an API key owner/admin operation intended for integrators managing their own customer accounts.

Authorization: string
in header

Use IdToken from the Login response as the Authorization header

x-api-key: string
in header

Use ApiKey from the Login response as the x-api-key header

Operation successfully processed. See response.

400 Bad Request

Request validation error

401 Unauthorized

Unauthorized

403 Forbidden

Unauthenticated

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "Accounts": [],
  "ResponseCode": "..",
  "ResponseText": ".."
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (401 Unauthorized)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (403 Forbidden)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

Pgp

Pgp

DeleteKey

DELETE /pgp

Reserved admin operation for deleting a registered PGP key by 8-character key id. The current deployed implementation validates authorization and key lookup, but returns pgpDelete is not yet supported; do not build production workflows that rely on key deletion yet.

Pgp parameters

Authorization: string
in header

Use IdToken from the Login response as the Authorization header

x-api-key: string
in header

Use ApiKey from the Login response as the x-api-key header

Request Example
{
  "PgpKeyId": "DBCBE671"
}
200 OK

Operation successfully processed. See response.

400 Bad Request

Request validation error

401 Unauthorized

Unauthorized

403 Forbidden

Unauthenticated

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (401 Unauthorized)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (403 Forbidden)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Pgp

ListKeys

GET /pgp

List PGP public keys registered for the authenticated account. authorize keys verify UploadFile signatures. export keys encrypt exported certificate private keys.

Authorization: string
in header

Use IdToken from the Login response as the Authorization header

x-api-key: string
in header

Use ApiKey from the Login response as the x-api-key header

200 OK

Operation successfully processed. See response.

400 Bad Request

Request validation error

401 Unauthorized

Unauthorized

403 Forbidden

Unauthenticated

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "PgpKeys": [],
  "ResponseCode": "..",
  "ResponseText": ".."
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (401 Unauthorized)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (403 Forbidden)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Pgp

UploadKey

PUT /pgp

Upload an ASCII-armored PGP public key for the authenticated admin account. Use purpose authorize for detached UploadFile signature verification, or export for encrypting ExportCert private-key material. The same PGP key cannot be registered for both purposes at the same time.

ASCII armored PGP Key in PgpKey and key purpose, i.e. export (exporting cert private key) or authorize (upload content authorization verification) in PgpKeyPurpose.\n\n NOTE: The same PGP key cannot be used for both export and authorize purpose at the same time.

Authorization: string
in header

Use IdToken from the Login response as the Authorization header

x-api-key: string
in header

Use ApiKey from the Login response as the x-api-key header

Request Content-Types: application/json
Request Example
{
  "PgpKey": "...",
  "PgpKeyPurpose": "authorize"
}
201 Created

Operation successfully processed. Resource created. See response.

400 Bad Request

Request validation error

401 Unauthorized

Unauthorized

403 Forbidden

Unauthenticated

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (201 Created)
{
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (401 Unauthorized)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (403 Forbidden)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

Session

Logout

DELETE /session/{Email}/{Mode}

Logout user.\n\n NOTE: AWS Cognito allows user logout, but the received authorization IdToken is still valid. When the optional AccessToken parameter is also provided, the IdToken is also revoked.

Authorization: string
in header

Use IdToken from the Login response as the Authorization header

x-api-key: string
in header

Use ApiKey from the Login response as the x-api-key header

Email: string
in path

Email address as the account username, e.g. user@example.com

Mode: string admin, data
in path

Administer account with admin mode, exchange files with data mode

200 OK

Operation successfully processed. See response.

400 Bad Request

Request validation error

401 Unauthorized

Unauthorized

403 Forbidden

Unauthenticated

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (401 Unauthorized)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (403 Forbidden)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

InitLogin

GET /session/{Email}/{Mode}

Before login, client must fetch challenge from the API. Then on login, the challenge must be passed along to the API (as response to the challenge). The challenge is always fresh for some period of time and the API validates it when passed with login. The challenge has form of base64-string|timestamp|uuid. For example:\n\nezwXceQ63fV9oWTSJBAE2Zq1Cw5tBIJe+7+Rl8jrgbk=|1475429754114|4017bda8-0a15-4154-a8b7-88069b05cb4e\n\n NOTE: The call must contain the same email as used for registration itself.

Email: string
in path

Email address as the account username, e.g. user@example.com

Mode: string admin, data
in path

Administer account with admin mode, exchange files with data mode

200 OK

Operation successfully processed. See response.

400 Bad Request

Request validation error

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "Challenge": "9Ty4zrnJGqNH0i1+I0OTKHjTs03Ymd4tBH70FTiYNhA=|1494962070679|2646b71b-9b51-4d11-bf5e-cca5617bcfde",
  "ResponseCode": "..",
  "ResponseText": ".."
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

Login

POST /session/{Email}/{Mode}

After getchallenge, call login with Email, Mode, and RSA encrypted admin or data account password and challenge timestamp. For further API calls (requiring authorization), include the received IdToken into the Authorization header of the request (pass idtoken as required parameter with the client SDK API calls). The IdToken expires in ExpiresIn seconds, after which new login must be performed.

NOTE: In case MFA Code is required, the call returns Session, ChallengeName, ResponseCode, and ResponseText as the login process continues with the LoginMFA API call. Echo ChallengeName back to LoginMFA so the API can distinguish SMS (SMS_MFA) from authenticator/TOTP (SOFTWARE_TOKEN_MFA) codes.

NOTE: If Email has not been yet verified, successful login provides only ResponseCode, ResponseText, and an AccessToken that must be used to verify email address.

CHALLENGE=$(curl -s https://ws-api.isecure.fi/v2/session/user@example.com/data | jq -r .Challenge)
TIMESTAMP=$(echo $CHALLENGE | cut -f 2 -d \|)
ENCRYPTED=$(echo -n testPassword..123455677098811\|\|$TIMESTAMP | openssl rsautl -oaep -encrypt -pubin -inkey prod.pem | base64)

Login body parameters

Email: string
in path

Email address as the account username, e.g. user@example.com

Mode: string admin, data
in path

Administer account with admin mode, exchange files with data mode

Request Content-Types: application/json
Request Example
{
  "ChResp": "ezwXceQ63fV9oWTSJBAE2Zq1Cw5tBIJe+7+Rl8jrgbk=|1475429754114|4017bda8-0a15-4154-a8b7-88069b05cb4e",
  "Encrypted": "..."
}
200 OK

Operation successfully processed. See response.

400 Bad Request

Request validation error

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "AccessToken": "eyJraWQiO...CzzcdcdAdEzKIcJPR7Fda0A",
  "ApiKey": "4vN6hGHrav31smM0Ha1k15MDlZKOEGn43UToWTt2",
  "ChallengeName": "SOFTWARE_TOKEN_MFA",
  "ExpiresIn": "3600",
  "IdToken": "eyJraWQiOiJ...jExlzbFU4GlGtml7AWQHDYi05IpA",
  "ResponseCode": "..",
  "ResponseText": "..",
  "Session": "xxxxxxxx"
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

LoginMFA

PUT /session/{Email}/{Mode}/mfacode

Send MFA Code along with the previously received Session token. For SMS MFA use the SMS code; for software-token MFA use the authenticator/TOTP code and echo ChallengeName: SOFTWARE_TOKEN_MFA. If Email has not been yet verified, successful login provides only ResponseCode, ResponseText, and an AccessToken that must be used to verify email address. If email is already verified and the login succeeds, add the IdToken from the login response as Authorization header in API requests requiring authorization (i.e. pass as parameter to client SDK API calls). IdToken expires in ExpiresIn seconds.

Session parameters

Email: string
in path

Email address as the account username, e.g. user@example.com

Mode: string admin, data
in path

Administer account with admin mode, exchange files with data mode

Request Content-Types: application/json
Request Example
{
  "ChallengeName": "SMS_MFA",
  "Code": "123456",
  "Session": "...",
  "SetupTOTP": "false"
}
200 OK

Operation successfully processed. See response.

400 Bad Request

Request validation error

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "AccessToken": "eyJraWQiO...CzzcdcdAdEzKIcJPR7Fda0A",
  "ApiKey": "4vN6hGHrav31smM0Ha1k15MDlZKOEGn43UToWTt2",
  "ExpiresIn": "3600",
  "IdToken": "eyJraWQiOiJ...jExlzbFU4GlGtml7AWQHDYi05IpA",
  "OtpauthUri": "otpauth://totp/ISECure:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=ISECure",
  "ResponseCode": "..",
  "ResponseText": "..",
  "SecretCode": "JBSWY3DPEHPK3PXP"
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

VerifyTOTP

PUT /session/{Email}/{Mode}/verifytotp

Confirm Google Authenticator (TOTP) enrollment. After a LoginMFA call with SetupTOTP: true, scan the returned OtpauthUri/SecretCode into an authenticator app and submit the generated 6-digit Code together with the AccessToken from that login response. On success, TOTP becomes the preferred MFA factor (SMS remains enabled as a fallback). No phone number parameter is required.

Session parameters

Email: string
in path

Email address as the account username, e.g. user@example.com

Mode: string admin
in path

TOTP enrollment is an admin mode operation

Request Content-Types: application/json
Request Example
{
  "AccessToken": "eyJraWQiO...CzzcdcdAdEzKIcJPR7Fda0A",
  "Code": "123456"
}
200 OK

Operation successfully processed. See response.

400 Bad Request

Request validation error

500 Internal Server Error

Unexpected error occurred

Response Content-Types: application/json
Response Example (200 OK)
{
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (400 Bad Request)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}
Response Example (500 Internal Server Error)
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

Schema Definitions

AccountDescriptor: object

AdminMode: string registered, unregistered

admin mode status

Certs: CertDescriptor
CertDescriptor
DataMode: string registered, unregistered

data mode status

Email: string

Email address as the account username

Export: string disabled, allowed

Status for certificate and private key export allowance. See ConfigCerts.

Name: string

Full name of registrant

Phone: string

Phone number with country code and + in front

Example
{
  "AdminMode": "registered",
  "Certs": [],
  "DataMode": "unregistered",
  "Email": "dan.forsberg@isecure.fi",
  "Export": "allowed",
  "Name": "Dan Forsberg",
  "Phone": "+358404835507"
}

CertDescriptor: object

CertName: string

Certificate common name

Expires: string

Date of expiry

Issuer: string

Certificate issuer

PEM: string

Certificate in PEM format

Serial: string

Certificate serial number

Subject: string

Certificate subject

Example
{
  "CertName": "osuuspankki_customer_signing_cert",
  "Expires": "Oct 28 06:30:08 2017 GMT",
  "Issuer": "CUSTOMER TEST OP-Pohjola WS CA",
  "PEM": "-----BEGIN CERTIFICATE-----\nMIIF+DCCA+CgAwIBAgIDEaBdMA0GCS...x0t6Cnd5lyGKg=\n-----END CERTIFICATE-----",
  "Serial": "11A05D",
  "Subject": "1000038023"
}

CertsAndKeys: object

Certificate: string

Certificate in PEM format

EncryptedPrivateKey: string

PGP encrypted ascii armored private key

Example
{
  "Certificate": "string",
  "EncryptedPrivateKey": "string"
}

ConfigCertsReq: object

Export: string

Set export to disabled to disallow certificate and private key pair exporting

Example
{
  "Export": "disabled"
}

DeleteKeyReq: object

PgpKeyId: string

8 chars hexadecimal PGP Key Id (see e.g. gpg --list-keys)

Example
{
  "PgpKeyId": "DBCBE671"
}

DownloadFileResp: object

Content: string

Downloaded file content as from bank (e.g. in Base64 form)

ResponseCode: string

Two digit response code in string format

ResponseText: string

Human readable response text

Example
{
  "Content": "xxxxxxxx",
  "ResponseCode": "..",
  "ResponseText": ".."
}

EnrollCertReq: object

Code: string

Full PIN code from bank (e.g. combined from SMS and letter)

Company: string

Company name as registered with bank (e.g. full capital letters, see contract). NOTE: The value of this field is not compared with the account company name set during registration because the format for cert enrollment differs between banks.

WsUserId: string

SEPA WebServices channel user id as in contract with bank

Example
{
  "Code": "8642603384107437",
  "Company": "ISECURE OY",
  "WsUserId": "..."
}

ErrorResponse: object

RequestId: string

Service side request id for problem tracing purposes

ResponseCode: string

Two digit response code in string format

ResponseText: string

Human readable response text

Example
{
  "RequestId": "string",
  "ResponseCode": "string",
  "ResponseText": "string"
}

ExportCertResp: object

CertsAndKeys: CertsAndKeys

List of certificate and encrypted private key pairs

CertsAndKeys
ResponseCode: string

Two digit response code in string format

ResponseText: string

Human readable response text

Example
{
  "CertsAndKeys": [],
  "ResponseCode": "..",
  "ResponseText": ".."
}

FileDescriptor: object

FileReference: string

File reference id, use e.g. when downloading the file

FileTimestamp: string

Creation time stamp of the file from bank

FileType: string

Bank specific file type

ServiceId: string

Bank specific service id (e.g. bank account number)

Status: string

File download status

TargetId: string

Bank specific target id

Example
{
  "FileReference": "227166",
  "FileTimestamp": "2017-05-20T03:36:21.148+03:00",
  "FileType": "VA",
  "ServiceId": "N/A",
  "Status": "NEW",
  "TargetId": "MLP"
}

ImportCertReq: object

Certificate: string

Certificate in PEM format

Company: string

Company name as registered with bank (e.g. full capital letters without Oy, see contract)

EncCertificate: string

Certificate in PEM format (encryption certificate for DanskeBank)

EncPrivatekey: string

Private key in PEM format (encryption certificate for DanskeBank)

PrivateKey: string

Private key in PEM format

WsUserId: string

SEPA WebServices channel user id as in contract with bank

Example
{
  "Certificate": "...",
  "Company": "ISECURE OY",
  "EncCertificate": "...",
  "EncPrivatekey": "...",
  "PrivateKey": "...",
  "WsUserId": "..."
}

InitLoginResp: object

Challenge: string

Challenge copied from API response

ResponseCode: string

Two digit response code in string format

ResponseText: string

Human readable response text

Example
{
  "Challenge": "9Ty4zrnJGqNH0i1+I0OTKHjTs03Ymd4tBH70FTiYNhA=|1494962070679|2646b71b-9b51-4d11-bf5e-cca5617bcfde",
  "ResponseCode": "..",
  "ResponseText": ".."
}

InitRegisterResp: object

Challenge: string

Challenge copied from API response

ResponseCode: string

Two digit response code in string format

ResponseText: string

Human readable response text

Example
{
  "Challenge": "9Ty4zrnJGqNH0i1+I0OTKHjTs03Ymd4tBH70FTiYNhA=|1494962070679|2646b71b-9b51-4d11-bf5e-cca5617bcfde",
  "ResponseCode": "..",
  "ResponseText": ".."
}

ListAccountsResp: object

Accounts: AccountDescriptor

List of accounts under the API key

AccountDescriptor
ResponseCode: string

Two digit response code in string format

ResponseText: string

Human readable response text

Example
{
  "Accounts": [],
  "ResponseCode": "..",
  "ResponseText": ".."
}

ListCertsResp: object

Certs: CertDescriptor

List of certificates

CertDescriptor
ResponseCode: string

Two digit response code in string format

ResponseText: string

Human readable response text

Example
{
  "Certs": [],
  "ResponseCode": "..",
  "ResponseText": ".."
}

ListFilesResp: object

FileDescriptors: FileDescriptor

List of downloadable files from bank

FileDescriptor
ResponseCode: string

Two digit response code in string format

ResponseText: string

Human readable response text

Example
{
  "FileDescriptors": [],
  "ResponseCode": "..",
  "ResponseText": ".."
}

ListKeysResp: object

PgpKeys: PgpKeyDescriptor

List of PGP keys in API

PgpKeyDescriptor
ResponseCode: string

Two digit response code in string format

ResponseText: string

Human readable response text

Example
{
  "PgpKeys": [],
  "ResponseCode": "..",
  "ResponseText": ".."
}

LoginMFAReq: object

ChallengeName: string

Echo the ChallengeName returned by the login response (SMS_MFA or SOFTWARE_TOKEN_MFA). Optional; defaults to SMS_MFA when omitted

Code: string

MFA code: SMS code (when ChallengeName is SMS_MFA) or authenticator/TOTP code (when SOFTWARE_TOKEN_MFA)

Session: string

Session token from login response

SetupTOTP: string

When true, a successful login also returns SecretCode, OtpauthUri, and AccessToken to begin Google Authenticator (TOTP) enrollment. Optional

Example
{
  "ChallengeName": "SMS_MFA",
  "Code": "123456",
  "Session": "...",
  "SetupTOTP": "false"
}

LoginMFAResp: object

AccessToken: string

Access token\n- Only present when Email verification is required, or when SetupTOTP was requested (held by the client in memory only, posted back to VerifyTOTP)

ApiKey: string

Integrator API Key\n- Not present when Email verification is required

ExpiresIn: string

Session expiration time\n- Not present when Email verification is required

IdToken: string

ID token\n- Not present when Email verification is required

OtpauthUri: string

otpauth:// URI for rendering the enrollment QR code\n- Only present when SetupTOTP was requested

ResponseCode: string

Two digit response code in string format

ResponseText: string

Human readable response text

SecretCode: string

TOTP shared secret\n- Only present when SetupTOTP was requested

Example
{
  "AccessToken": "eyJraWQiO...CzzcdcdAdEzKIcJPR7Fda0A",
  "ApiKey": "4vN6hGHrav31smM0Ha1k15MDlZKOEGn43UToWTt2",
  "ExpiresIn": "3600",
  "IdToken": "eyJraWQiOiJ...jExlzbFU4GlGtml7AWQHDYi05IpA",
  "OtpauthUri": "otpauth://totp/ISECure:user@example.com?secret=JBSWY3DPEHPK3PXP&issuer=ISECure",
  "ResponseCode": "..",
  "ResponseText": "..",
  "SecretCode": "JBSWY3DPEHPK3PXP"
}

LoginReq: object

ChResp: string

Challenge copied from API response

Encrypted: string

RSA encrypted password and timestamp

Example
{
  "ChResp": "ezwXceQ63fV9oWTSJBAE2Zq1Cw5tBIJe+7+Rl8jrgbk=|1475429754114|4017bda8-0a15-4154-a8b7-88069b05cb4e",
  "Encrypted": "..."
}

LoginResp: object

AccessToken: string

Access token\n- Not present on MFA login initiation, i.e. admin mode\n- Only present when Email verification is required

ApiKey: string

Integrator API Key\n- Not present on MFA login initiation, i.e. admin mode)

ChallengeName: string

MFA challenge returned by Cognito\n- Only present on MFA login initiation (SMS_MFA or SOFTWARE_TOKEN_MFA)

ExpiresIn: string

Session expiration time\n- Not present on MFA login initiation, i.e. admin mode)

IdToken: string

ID token\n- Not present on MFA login initiation, i.e. admin mode

ResponseCode: string

Two digit response code in string format

ResponseText: string

Human readable response text

Session: string

Session token\n- Only present on MFA login initiation, i.e. admin mode)

Example
{
  "AccessToken": "eyJraWQiO...CzzcdcdAdEzKIcJPR7Fda0A",
  "ApiKey": "4vN6hGHrav31smM0Ha1k15MDlZKOEGn43UToWTt2",
  "ChallengeName": "SOFTWARE_TOKEN_MFA",
  "ExpiresIn": "3600",
  "IdToken": "eyJraWQiOiJ...jExlzbFU4GlGtml7AWQHDYi05IpA",
  "ResponseCode": "..",
  "ResponseText": "..",
  "Session": "xxxxxxxx"
}

PasswordResetReq: object

ChResp: string

Challenge copied from API response

Code: string

Code from SMS

Encrypted: string

RSA encrypted NEW password and timestamp

Example
{
  "ChResp": "ezwXceQ63fV9oWTSJBAE2Zq1Cw5tBIJe+7+Rl8jrgbk=|1475429754114|4017bda8-0a15-4154-a8b7-88069b05cb4e",
  "Code": "123456",
  "Encrypted": "..."
}

PgpKeyDescriptor: object

PgpKeyId: string

Short version of a PGP Key id identifying the key, e.g. 3A3A59B2

PgpKeyPurpose: string export, authorize

PGP Key purpose

Example
{
  "PgpKeyId": "3A3A59B2",
  "PgpKeyPurpose": "authorize"
}

RegisterReq: object

ApiKey: string

Integrator API Key, or 0 if not already known (e.g. initial integrator registration)

ChResp: string

Challenge copied from API response

Company: string

Company name

Encrypted: string

RSA encrypted password and timestamp

Name: string

Full name of registrant

Phone: string

Phone number with country code and + in front

Example
{
  "ApiKey": "hzYAVO9Sg98nsNh81M84O2kyXVy6K1xwHD8",
  "ChResp": "ezwXceQ63fV9oWTSJBAE2Zq1Cw5tBIJe+7+Rl8jrgbk=|1475429754114|4017bda8-0a15-4154-a8b7-88069b05cb4e",
  "Company": "ISECure Oy",
  "Encrypted": "...",
  "Name": "Dan Forsberg",
  "Phone": "+358404835507"
}

RegisterResp: object

ApiKey: string

Integrator API Key

ResponseCode: string

Two digit response code in string format

ResponseText: string

Human readable response text

Example
{
  "ApiKey": "4vN6hGHrav31smM0Ha1k15MDlZKOEGn43UToWTt2",
  "ResponseCode": "..",
  "ResponseText": ".."
}

Response: object

ResponseCode: string

Two digit response code in string format

ResponseText: string

Human readable response text

Example
{
  "ResponseCode": "string",
  "ResponseText": "string"
}

ShareCertsResp: object

ResponseCode: string

Two digit response code in string format

ResponseText: string

Human readable response text

SharedFrom: string[]

ExtEmail account that this account shares certs from

string
SharedTo: string[]

ExtEmail account that this account shares certs for

string
Example
{
  "ResponseCode": "..",
  "ResponseText": "..",
  "SharedFrom": [],
  "SharedTo": []
}

UnshareCertsResp: object

ResponseCode: string

Two digit response code in string format

ResponseText: string

Human readable response text

SharedFrom: string[]

ExtEmail account that this account shares certs from

string
SharedTo: string[]

ExtEmail account that this account shares certs for

string
Example
{
  "ResponseCode": "..",
  "ResponseText": "..",
  "SharedFrom": [],
  "SharedTo": []
}

UploadFileReq: object

FileContents: string

Base64 encoded file contents

FileName: string

Upload file name

FileType: string

Bank specific file type

Signature: string

Detached PGP signature(s) made with registered PGP key(s)

Example
{
  "FileContents": "...",
  "FileName": "testfile",
  "FileType": "KTL",
  "Signature": "string"
}

UploadKeyReq: object

PgpKey: string

ASCII armored PGP Key

PgpKeyPurpose: string

PGP key purpose, i.e. export (exporting cert private key) or authorize (upload content authorization verification).

Example
{
  "PgpKey": "...",
  "PgpKeyPurpose": "authorize"
}

VerifyEmailReq: object

AccessToken: string

Access token from login response

Code: string

Code from email

Example
{
  "AccessToken": "eyJraWQiO...CzzcdcdAdEzKIcJPR7Fda0A",
  "Code": "123456"
}

VerifyPhoneReq: object

Code: string

Code from SMS

Example
{
  "Code": "123456"
}

VerifyTOTPReq: object

AccessToken: string

AccessToken returned by LoginMFA when SetupTOTP was requested (held by the client in memory only)

Code: string

6-digit code from the authenticator app

Example
{
  "AccessToken": "eyJraWQiO...CzzcdcdAdEzKIcJPR7Fda0A",
  "Code": "123456"
}