Download OpenAPI specification:Download
The CIP Partner API exposes a JWT-authenticated surface for trusted partners to manage B2B tenants they own, onboard cardholders under those tenants, operate individual accounts they onboard directly, create and operate cards under any of those accounts, and query fees / delivery options.
All endpoints are mounted under /api/partner and require an ES512
Bearer JWT whose iss matches the partner's registered URL and whose
sub equals the partner's _id.
Generate a P-521 (secp521r1) ES512 keypair and provide the public key
to Paynovus — it is stored on the Partner record.
Sign a JWT with the partner's private key. The token must contain:
{
"iss": "https://your-registered-url.com",
"sub": "<partnerObjectId>",
"exp": <unix-seconds, +1 minute>,
"iat": <unix-seconds>
}
Send the token on every request:
Authorization: Bearer <jwt>
Partners are pre-trusted: a successful JWT verification pass grants full access to every resource owned by the calling partner. No additional role or permission checks are required from the caller.
All endpoints automatically scope their results to the calling partner —
if you pass an :id that does not belong to your partner, the endpoint
returns 404 Not Found with no further detail, regardless of whether
the resource exists in another partner's scope.
Endpoints that target the authenticated partner itself (/health-check,
/me). Useful for connectivity checks and self-introspection.
Returns the authenticated partner profile along with every B2B tenant and individual onboarding owned by that partner.
The b2bAccounts and individuals arrays are returned in full. This
endpoint does not paginate and does not return a separate count field
for either array; use the array lengths when counts are needed.
The response always reflects exactly the authenticated partner.
object (Partner) | |
| activeTenantId | string or null The B2B tenant this request was scoped to (null when the partner has no B2B tenant — common for individual-only partners). |
Array of objects (B2BTenant) | |
Array of objects (IndividualAccountSummary) |
{- "partner": {
- "_id": "string",
- "name": "string",
- "status": "active",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}, - "activeTenantId": "string",
- "b2bAccounts": [
- {
- "_id": "string",
- "cardholderSequence": 0,
- "customer": true,
- "programmeManagers": [
- "string"
], - "status": "pending",
- "products": [
- "string"
], - "permissions": [ ],
- "businessSector": "string",
- "regions": "string",
- "countries": "string",
- "businessPurpose": "string",
- "cardUserGroups": "string",
- "numberOfCards": 0,
- "applicationSource": "string",
- "partner": "string",
- "IBANs": [
- {
- "IBAN": "string",
- "currencyType": "string",
- "isActive": true
}
], - "addresses": [
- {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "city": "string",
- "zipCode": "string",
- "country": "string",
- "_id": "string"
}
], - "permissionAudit": [ ],
- "permissionsLog": [ ],
- "companyName": "string",
- "phoneNumber": "string",
- "email": "user@example.com",
- "registrationNumber": "string",
- "companyIndustry": "string",
- "countryOfIncorporation": "string",
- "contactName": "string",
- "contactEmail": "user@example.com",
- "typeOfBusiness": "string",
- "cardUsage": "string",
- "cardholderGroups": "string",
- "fundLoading": "string",
- "clientCode": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "__v": 0,
- "approvedAt": "2019-08-24T14:15:22Z",
- "approvedBy": "string",
- "authPhoneNumber": "string",
- "balanceNotifications": [ ]
}
], - "individuals": [
- {
- "_id": "string",
- "clientID": "string",
- "personalInfo": {
- "firstName": "string",
- "middleName": "string",
- "lastName": "string",
- "email": "user@example.com",
- "phoneNumber": "string",
- "birthDate": "2019-08-24T14:15:22Z",
- "birthCountry": "string",
- "authPhoneNumber": "string"
}, - "address": {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "city": "string",
- "stateProvince": "string",
- "zipCode": "string",
- "country": "string"
}, - "applicationStatus": "PENDING",
- "dashboardStatus": "ACTIVE",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
]
}Partner-owned B2B tenants and the cardholders that live under them.
Tenants are created by PayNovus on the partner's behalf — partners
can list, fetch, and operate on tenants they're already linked to.
Cardholder creation under a tenant is partner-driven and goes through
a PayNovus approval task (returned as PENDING).
Returns every B2B tenant linked to your partner. The endpoint is
full-list: it does not paginate and the entire array is returned
in a single response with a count field.
The response is intentionally minimal — only the fields a partner
needs to render a tenant-picker UI. Pull the full tenant details
(IBANs, products, status, contacts) via
GET /business/accounts/{b2bAccountId}.
| count required | integer |
required | Array of objects (PartnerB2BAccountListItem) |
{- "count": 0,
- "data": [
- {
- "_id": "string",
- "companyName": "string",
- "clientCode": "string",
- "status": "string",
- "email": "user@example.com",
- "phoneNumber": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
]
}Returns the tenant document plus the linked debit-account rows it
owns. If the :b2bAccountId does not belong to your partner,
the response is 404 Not Found — identical whether the tenant
does not exist or belongs to another partner (no enumeration).
| b2bAccountId required | string B2B tenant identifier — must be owned by the calling partner. |
| success | boolean |
object (B2BTenant) | |
object (DebitAccount) A debit account (IBAN) linked to a tenant or cardholder. | |
Array of objects (DebitAccount) |
{- "success": true,
- "data": {
- "_id": "string",
- "cardholderSequence": 0,
- "customer": true,
- "programmeManagers": [
- "string"
], - "status": "pending",
- "products": [
- "string"
], - "permissions": [ ],
- "businessSector": "string",
- "regions": "string",
- "countries": "string",
- "businessPurpose": "string",
- "cardUserGroups": "string",
- "numberOfCards": 0,
- "applicationSource": "string",
- "partner": "string",
- "IBANs": [
- {
- "IBAN": "string",
- "currencyType": "string",
- "isActive": true
}
], - "addresses": [
- {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "city": "string",
- "zipCode": "string",
- "country": "string",
- "_id": "string"
}
], - "permissionAudit": [ ],
- "permissionsLog": [ ],
- "companyName": "string",
- "phoneNumber": "string",
- "email": "user@example.com",
- "registrationNumber": "string",
- "companyIndustry": "string",
- "countryOfIncorporation": "string",
- "contactName": "string",
- "contactEmail": "user@example.com",
- "typeOfBusiness": "string",
- "cardUsage": "string",
- "cardholderGroups": "string",
- "fundLoading": "string",
- "clientCode": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "__v": 0,
- "approvedAt": "2019-08-24T14:15:22Z",
- "approvedBy": "string",
- "authPhoneNumber": "string",
- "balanceNotifications": [ ]
}, - "debitAccount": {
- "_id": "string",
- "owners": [
- {
- "clientCode": "string",
- "relationship": "OWN",
- "mainOwner": true,
- "_id": "string"
}
], - "b2bCompany": "string",
- "isCompany": true,
- "isB2b": true,
- "accountNumber": "string",
- "accountHolder": "string",
- "currencyCode": "string",
- "currency": "string",
- "status": "ACTIVE",
- "clientCode": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "__v": 0,
- "accountType": "string",
- "accountTypeSyncedAt": "2019-08-24T14:15:22Z"
}, - "debitAccounts": [
- {
- "_id": "string",
- "owners": [
- {
- "clientCode": "string",
- "relationship": "OWN",
- "mainOwner": true,
- "_id": "string"
}
], - "b2bCompany": "string",
- "isCompany": true,
- "isB2b": true,
- "accountNumber": "string",
- "accountHolder": "string",
- "currencyCode": "string",
- "currency": "string",
- "status": "ACTIVE",
- "clientCode": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "__v": 0,
- "accountType": "string",
- "accountTypeSyncedAt": "2019-08-24T14:15:22Z"
}
]
}Returns the live availableBalance for each IBAN linked to the
tenant.
Per-IBAN failure handling. Any IBAN whose balance cannot be
resolved is surfaced in the response with status: "error" and
an errorMessage field — failures are never silently
reported as zero. The overall HTTP status remains 200 so a
partner UI can still render the IBANs that succeeded.
| b2bAccountId required | string B2B tenant identifier — must be owned by the calling partner. |
| success | boolean |
| count | integer |
Array of objects (BalanceEntry) |
{- "success": true,
- "count": 0,
- "data": [
- {
- "iban": "string",
- "availableBalance": 0,
- "currency": "string",
- "accountHolder": "string",
- "isB2bShared": true,
- "accountStatus": "string",
- "status": "ok",
- "errorMessage": "string"
}
]
}Returns the tenant's debit accounts that are eligible for issuing a new card. Mirrors the same eligibility filter the Dashboard uses (active status, primary currency resolved).
The returned shape mirrors Account; pass any of these IBANs to
a card-creation endpoint's accNo parameter.
| b2bAccountId required | string B2B tenant identifier — must be owned by the calling partner. |
| success | boolean |
| count | integer |
Array of objects (B2BIssuableIbanAccount) |
{- "success": true,
- "count": 0,
- "accounts": [
- {
- "_id": "string",
- "b2bAccountId": "string",
- "companyName": "string",
- "clientCode": "string",
- "accountNumber": "string",
- "currency": "string",
- "label": "string",
- "description": "string",
- "status": "string",
- "accountType": "string",
- "isActive": true,
- "isPrimary": true,
- "linkedCardsCount": 0,
- "activeCardsCount": 0,
- "createdAt": "2019-08-24T14:15:22Z"
}
]
}Submits a settings change (name, isActive, isPrimary) for an
existing linked IBAN. Like the admin-side equivalent, the change
goes through an approval task: the partner gets back a
taskId/status: PENDING and PayNovus applies the change once it
is approved.
At least one of name, isActive, or isPrimary must be
supplied. isPrimary only accepts true (a tenant must always
have one primary account — the way to move the primary is to set a
different IBAN, not to clear the current one).
| b2bAccountId required | string B2B tenant identifier — must be owned by the calling partner. |
| Idempotency-Key | string <uuid> Example: 550e8400-e29b-41d4-a716-446655440000 Optional idempotency key to ensure safe retries for non-GET requests. When provided, the API remembers your request and returns the exact same result if the same key is sent within 60 seconds. This protects against duplicate operations in case of network timeouts or accidental retries. Recommended: Use a UUID v4 for each logical operation. Response headers:
|
| IBAN required | string = 22 characters IBAN whose settings are being changed. Exactly 22 characters. |
| name | string <= 100 characters Optional display label; pass empty string to clear. |
| isActive | boolean When |
| isPrimary | boolean Value: true Only |
{- "IBAN": "BG44TRUD40059780005961",
- "name": "Payroll Account",
- "isActive": true,
- "isPrimary": true
}{- "success": true,
- "message": "string",
- "b2bAccountId": "string",
- "taskId": "string",
- "status": "PENDING"
}Returns the ProductVersion documents linked to the tenant.
Without the kind query parameter the endpoint returns every
product.
Each product carries its own per-product card-limit envelopes
under limits (e.g. ATM_CCA_LMT, POS_PUR_LMT). The limits
field is omitted on products that have no configured envelopes.
| b2bAccountId required | string B2B tenant identifier — must be owned by the calling partner. |
| kind | string Enum: "virtual" "physical" Optional filter — when set to |
| success | boolean |
Array of objects (ProductVersion) |
{- "success": true,
- "products": [
- {
- "_id": "string",
- "version_name": "string",
- "version_code": "string",
- "version": "string",
- "status": "string",
- "reason": "string",
- "reasonUpdatedAt": "2019-08-24T14:15:22Z",
- "company": "string",
- "created_by": "string",
- "deleted_at": "2019-08-24T14:15:22Z",
- "created_at": "2019-08-24T14:15:22Z",
- "__v": 0,
- "limits": {
- "property1": {
- "defaultValue": 0,
- "maxValue": 0
}, - "property2": {
- "defaultValue": 0,
- "maxValue": 0
}
}
}
]
}Paginated audit log for the tenant. Defaults: page=1,
limit=50. No hard server-side cap on limit.
Filters can be combined: ?action=LOCK_CARD&result=SUCCESS&from=2025-01-01.
Tenant ownership is verified against the calling partner;
foreign tenants return 404.
| b2bAccountId required | string B2B tenant identifier — must be owned by the calling partner. |
| page | integer >= 1 Default: 1 Example: page=1 Page number for pagination. Starts at |
| limit | integer >= 1 Default: 50 Example: limit=50 Number of audit-log or card-status-history records to return per
page. Defaults to |
| from | string <date-time> Inclusive lower bound on the entry's |
| to | string <date-time> Inclusive upper bound on the entry's |
| sort | string Sort order, comma-separated |
| cardId | string Filter by card |
| customerId | string Filter by cardholder |
| action | string Filter by action name (e.g. |
| result | string Enum: "SUCCESS" "FAILED" Filter by outcome. |
| success | boolean |
Array of objects (AuditLogEntry) | |
object (Pagination) |
{- "success": true,
- "data": [
- {
- "_id": "string",
- "logRequestId": "string",
- "userId": "string",
- "partnerId": "string",
- "customerId": "string",
- "cardId": "string",
- "b2bAccountId": "string",
- "targetUserId": "string",
- "eventTaskId": "string",
- "entityType": "string",
- "entityId": "string",
- "ipAddress": "string",
- "action": "CREATE_VIRTUAL_CARD",
- "result": "SUCCESS",
- "oldData": { },
- "newData": { },
- "errorMessage": null,
- "createdAt": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "page": 0,
- "limit": 0,
- "total": 0,
- "pages": 0,
- "hasNextPage": true,
- "hasPrevPage": true
}
}Paginated card-status history across every card issued under the
tenant. Defaults: page=1, limit=50. No hard server-side cap on
limit.
Filters can be combined: ?fromStatus=ACTIVE&toStatus=LOCKED&triggeredBy=PARTNER.
| b2bAccountId required | string B2B tenant identifier — must be owned by the calling partner. |
| page | integer >= 1 Default: 1 Example: page=1 Page number for pagination. Starts at |
| limit | integer >= 1 Default: 50 Example: limit=50 Number of audit-log or card-status-history records to return per
page. Defaults to |
| from | string <date-time> Inclusive lower bound on the entry's |
| to | string <date-time> Inclusive upper bound on the entry's |
| sort | string Sort order, comma-separated |
| cardId | string Filter by card |
| fromStatus | string Filter by the card status before the change. Accepts either the
status name (e.g. |
| toStatus | string Filter by the card status after the change. Accepts either the
status name (e.g. |
| triggeredBy | string Enum: "PARTNER" "USER" "SYSTEM" Filter by who drove the status change. |
| triggeredByUserId | string Filter by the dashboard user that drove the change (only set when
|
| success | boolean |
Array of objects (CardStatusHistoryEntry) | |
object (Pagination) |
{- "success": true,
- "data": [
- {
- "_id": "string",
- "logRequestId": "string",
- "cardId": "string",
- "customerId": "string",
- "customerMongoId": "string",
- "fromStatus": "ACTIVE",
- "toStatus": "ACTIVE",
- "triggeredBy": "PARTNER",
- "triggeredByUserId": "string",
- "triggeredByPartnerId": "string",
- "ipAddress": "string",
- "createdAt": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "page": 0,
- "limit": 0,
- "total": 0,
- "pages": 0,
- "hasNextPage": true,
- "hasPrevPage": true
}
}Paginated transactions for the tenant. Defaults: page=1,
limit=10. No hard server-side cap on limit.
| b2bAccountId required | string B2B tenant identifier — must be owned by the calling partner. |
| page | integer >= 1 Default: 1 Example: page=1 Page number for pagination. Starts at |
| limit | integer >= 1 Default: 10 Example: limit=10 Number of transactions to return per page. Defaults to |
Array of objects (Transaction) | |
object |
{- "transactions": [
- {
- "transactionProcessingCode": "string",
- "transactionAmount": 0,
- "billingAmount": 0,
- "transactionDatetime": "string",
- "localTransactionTime": "2019-08-24T14:15:22Z",
- "conversionRate": "string",
- "traceNumber": "string",
- "cardExpiryDate": "string",
- "retrievalReference": "string",
- "terminalId": "string",
- "merchantId": "string",
- "merchantLocation": "string",
- "cardId": "string",
- "currencyTransaction": "string",
- "currencyBilling": "string",
- "accountIdentification": "string",
- "customFields": {
- "transactionInfo": "string",
- "paypalReference": "string"
}, - "extendedData": {
- "authorizationLevel": "string",
- "authorizationMethod": "string",
- "productCode": "string",
- "deviceId": "string",
- "channelId": "string",
- "riskScore": "string",
- "retryCount": "string",
- "trackingId": "string"
}, - "resolvent": {
- "type": "denied",
- "resolved": true,
- "date": "2019-08-24T14:15:22Z"
}, - "processingOutcome": {
- "approved": true,
- "declineReasonCode": "string"
}, - "fees": {
- "taxType": "string",
- "taxAmount": 0,
- "taxAmountFx": 0,
- "taxNarrative": "string"
}, - "externalToken": "string",
- "transType": {
- "codeOraSys": "string",
- "description": "string",
- "action": "DR",
- "directionType": "D",
- "ryvylLabel": "string",
- "ryvylStatement": "string",
- "mcc": "string",
- "settlementCode": "string"
}, - "transStatus": "pending",
- "createdAt": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "total": 0,
- "page": 0,
- "limit": 0,
- "totalPages": 0
}
}Returns every cardholder owned by the calling partner across all
linked B2B tenants and direct partner-owned individual
onboardings. Unlike /business/accounts/{b2bAccountId}/cardholders
(tenant-scoped), this endpoint is partner-wide.
The list includes B2B self-admin records (a tenant manager who is also a cardholder) — those still belong to the partner.
Full-list response — no pagination. The response includes the
tenant snapshot (companyName, clientCode, status) for the
b2bClient of each cardholder when populated.
| success | boolean |
| count | integer |
Array of objects (IndividualOnboardingRecord) |
{- "success": true,
- "count": 0,
- "data": [
- {
- "_id": "string",
- "origin": "API",
- "company": "string",
- "productVersion": [
- "string"
], - "personalInfo": {
- "firstName": "string",
- "middleName": "string",
- "lastName": "string",
- "mothersMaidenName": "string",
- "email": "string",
- "phoneNumber": "string",
- "phone": "string",
- "authPhoneNumber": "string",
- "birthDate": "2019-08-24T14:15:22Z",
- "birthCountry": "string",
- "dateOfBirth": "2019-08-24T14:15:22Z"
}, - "address": {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "city": "string",
- "stateProvince": "string",
- "zipCode": "string",
- "country": "string"
}, - "deliveryAddress": [
- {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "city": "string",
- "stateProvince": "string",
- "zipCode": "string",
- "country": "string",
- "_id": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
], - "idDocument": {
- "customerIdType": "PASSPORT",
- "number": "string",
- "issueDate": "2019-08-24T14:15:22Z",
- "expiryDate": "2019-08-24T14:15:22Z",
- "issuingCountry": "string",
- "frontImagePath": "string",
- "backImagePath": "string",
- "idAuthority": "string"
}, - "taxInfo": {
- "country": "string",
- "taxIdNumber": "string"
}, - "clientID": "string",
- "cardTypes": [
- "string"
], - "cardCurrency": [
- "string"
], - "client": true,
- "permissions": [
- "string"
], - "permissionAudit": [
- {
- "key": "string",
- "enabled": true
}
], - "permissionsLog": [
- { }
], - "legalId": "string",
- "firmOccupation": "string",
- "embossedName1": "string",
- "embossedName2": "string",
- "citizenship": "string",
- "riskLevel": 0,
- "riskStatus": "string",
- "operationStatus": "Active",
- "applicationId": "string",
- "applicationStatus": "PENDING",
- "applicationDate": "2019-08-24T14:15:22Z",
- "dashboardStatus": "ACTIVE",
- "userType": "b2b",
- "partner": "string",
- "b2bClient": "string",
- "isSelfAdmin": true,
- "createdOnBehalfOf": "string",
- "maxVirtualCards": 0,
- "maxPhysicalCards": 0,
- "hasCompletedBiometrics": true,
- "isPep": true,
- "pepUnderstanding": "yes_i_do",
- "pepAcknowledgement": true,
- "uboPepStatement": { },
- "hasAgreedToTerms": true,
- "hasAgreedToTariffs": true,
- "hasAgreedToCardholderLimitation": true,
- "hasAgreedToNoThirdPartyCards": true,
- "hasAgreedToCompanyLiability": true,
- "isPartnerIndividualProcessFinished": true,
- "orasysRequest": {
- "isAllOrasysAccountCreated": true,
- "createCustomerAccount": {
- "isCreated": true,
- "settlementCurrenciesCreated": [
- "string"
], - "requestCreateRetryCount": 0,
- "requestCreateErrors": [
- "string"
], - "requestGetRetryCount": 0,
- "requestGetErrors": [
- "string"
], - "createdAt": "2019-08-24T14:15:22Z",
- "requestCreateLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestGetLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestId": "string",
- "accountId": 0
}, - "createAccountType412100": {
- "isCreated": true,
- "settlementCurrenciesCreated": [
- "string"
], - "requestCreateRetryCount": 0,
- "requestCreateErrors": [
- "string"
], - "requestGetRetryCount": 0,
- "requestGetErrors": [
- "string"
], - "createdAt": "2019-08-24T14:15:22Z",
- "requestCreateLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestGetLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestId": "string",
- "accountId": 0
}, - "createAccountType412200": {
- "isCreated": true,
- "settlementCurrenciesCreated": [
- "string"
], - "requestCreateRetryCount": 0,
- "requestCreateErrors": [
- "string"
], - "requestGetRetryCount": 0,
- "requestGetErrors": [
- "string"
], - "createdAt": "2019-08-24T14:15:22Z",
- "requestCreateLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestGetLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestId": "string",
- "accountId": 0
}, - "createAccountType414000": {
- "isCreated": true,
- "settlementCurrenciesCreated": [
- "string"
], - "requestCreateRetryCount": 0,
- "requestCreateErrors": [
- "string"
], - "requestGetRetryCount": 0,
- "requestGetErrors": [
- "string"
], - "createdAt": "2019-08-24T14:15:22Z",
- "requestCreateLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestGetLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestId": "string",
- "accountId": 0,
- "IBAN": "string"
}
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "__v": 0
}
]
}Lists every IndividualOnboarding record whose b2bClient matches
the tenant. The list excludes self-admin rows
(isSelfAdmin !== true) so it returns end-user cardholders,
not the tenant-manager themselves.
Full-list response — no pagination. The response is the full onboarding document.
| b2bAccountId required | string B2B tenant identifier — must be owned by the calling partner. |
| success | boolean |
| count | integer |
Array of objects (IndividualOnboardingRecord) |
{- "success": true,
- "count": 0,
- "data": [
- {
- "_id": "string",
- "origin": "API",
- "company": "string",
- "productVersion": [
- "string"
], - "personalInfo": {
- "firstName": "string",
- "middleName": "string",
- "lastName": "string",
- "mothersMaidenName": "string",
- "email": "string",
- "phoneNumber": "string",
- "phone": "string",
- "authPhoneNumber": "string",
- "birthDate": "2019-08-24T14:15:22Z",
- "birthCountry": "string",
- "dateOfBirth": "2019-08-24T14:15:22Z"
}, - "address": {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "city": "string",
- "stateProvince": "string",
- "zipCode": "string",
- "country": "string"
}, - "deliveryAddress": [
- {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "city": "string",
- "stateProvince": "string",
- "zipCode": "string",
- "country": "string",
- "_id": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
], - "idDocument": {
- "customerIdType": "PASSPORT",
- "number": "string",
- "issueDate": "2019-08-24T14:15:22Z",
- "expiryDate": "2019-08-24T14:15:22Z",
- "issuingCountry": "string",
- "frontImagePath": "string",
- "backImagePath": "string",
- "idAuthority": "string"
}, - "taxInfo": {
- "country": "string",
- "taxIdNumber": "string"
}, - "clientID": "string",
- "cardTypes": [
- "string"
], - "cardCurrency": [
- "string"
], - "client": true,
- "permissions": [
- "string"
], - "permissionAudit": [
- {
- "key": "string",
- "enabled": true
}
], - "permissionsLog": [
- { }
], - "legalId": "string",
- "firmOccupation": "string",
- "embossedName1": "string",
- "embossedName2": "string",
- "citizenship": "string",
- "riskLevel": 0,
- "riskStatus": "string",
- "operationStatus": "Active",
- "applicationId": "string",
- "applicationStatus": "PENDING",
- "applicationDate": "2019-08-24T14:15:22Z",
- "dashboardStatus": "ACTIVE",
- "userType": "b2b",
- "partner": "string",
- "b2bClient": "string",
- "isSelfAdmin": true,
- "createdOnBehalfOf": "string",
- "maxVirtualCards": 0,
- "maxPhysicalCards": 0,
- "hasCompletedBiometrics": true,
- "isPep": true,
- "pepUnderstanding": "yes_i_do",
- "pepAcknowledgement": true,
- "uboPepStatement": { },
- "hasAgreedToTerms": true,
- "hasAgreedToTariffs": true,
- "hasAgreedToCardholderLimitation": true,
- "hasAgreedToNoThirdPartyCards": true,
- "hasAgreedToCompanyLiability": true,
- "isPartnerIndividualProcessFinished": true,
- "orasysRequest": {
- "isAllOrasysAccountCreated": true,
- "createCustomerAccount": {
- "isCreated": true,
- "settlementCurrenciesCreated": [
- "string"
], - "requestCreateRetryCount": 0,
- "requestCreateErrors": [
- "string"
], - "requestGetRetryCount": 0,
- "requestGetErrors": [
- "string"
], - "createdAt": "2019-08-24T14:15:22Z",
- "requestCreateLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestGetLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestId": "string",
- "accountId": 0
}, - "createAccountType412100": {
- "isCreated": true,
- "settlementCurrenciesCreated": [
- "string"
], - "requestCreateRetryCount": 0,
- "requestCreateErrors": [
- "string"
], - "requestGetRetryCount": 0,
- "requestGetErrors": [
- "string"
], - "createdAt": "2019-08-24T14:15:22Z",
- "requestCreateLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestGetLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestId": "string",
- "accountId": 0
}, - "createAccountType412200": {
- "isCreated": true,
- "settlementCurrenciesCreated": [
- "string"
], - "requestCreateRetryCount": 0,
- "requestCreateErrors": [
- "string"
], - "requestGetRetryCount": 0,
- "requestGetErrors": [
- "string"
], - "createdAt": "2019-08-24T14:15:22Z",
- "requestCreateLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestGetLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestId": "string",
- "accountId": 0
}, - "createAccountType414000": {
- "isCreated": true,
- "settlementCurrenciesCreated": [
- "string"
], - "requestCreateRetryCount": 0,
- "requestCreateErrors": [
- "string"
], - "requestGetRetryCount": 0,
- "requestGetErrors": [
- "string"
], - "createdAt": "2019-08-24T14:15:22Z",
- "requestCreateLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestGetLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestId": "string",
- "accountId": 0,
- "IBAN": "string"
}
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "__v": 0
}
]
}Submits a new B2B cardholder for PayNovus approval. The resulting
onboarding starts in applicationStatus: PENDING; a taskId is
returned so the partner can poll for the approval outcome.
You are not asked to provide a Dashboard user — there is no
password to set for the cardholder on this surface. If the
supplied email is already in use under the same tenant, the
endpoint rejects the request with 409 Conflict before the
onboarding is created.
| b2bAccountId required | string B2B tenant identifier — must be owned by the calling partner. |
| Idempotency-Key | string <uuid> Example: 550e8400-e29b-41d4-a716-446655440000 Optional idempotency key to ensure safe retries for non-GET requests. When provided, the API remembers your request and returns the exact same result if the same key is sent within 60 seconds. This protects against duplicate operations in case of network timeouts or accidental retries. Recommended: Use a UUID v4 for each logical operation. Response headers:
|
required | object |
required | object |
required | object |
required | object |
| citizenship required | string <= 40 characters ISO 3166-1 alpha-2 country code. |
| embossedName1 required | string Primary line printed on the card. |
| embossedName2 required | string Secondary line printed on the card (often the company name). |
| firmOccupation required | string <= 40 characters |
| hasCompletedBiometrics required | boolean |
| isPep required | boolean |
| pepUnderstanding | string Enum: "yes_i_do" "need_more_info" Required when |
| pepAcknowledgement | boolean Required when |
| hasAgreedToTerms | boolean |
| hasAgreedToTariffs | boolean |
| hasAgreedToCardholderLimitation | boolean |
| hasAgreedToNoThirdPartyCards | boolean |
| hasAgreedToCompanyLiability | boolean |
| uboPepStatement | object Required when |
{- "personalInfo": {
- "firstName": "string",
- "secondName": "string",
- "lastName": "string",
- "email": "user@example.com",
- "phoneNumber": "string",
- "birthDate": "1990-05-20",
- "birthCountry": "string"
}, - "address": {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "city": "string",
- "zipCode": "string",
- "country": "str",
- "stateProvince": "string"
}, - "idDocument": {
- "customerIdType": "ID",
- "number": "string",
- "issueDate": "string",
- "expiryDate": "string",
- "issuingCountry": "string",
- "idAuthority": "string"
}, - "taxInfo": {
- "country": "string",
- "taxIdNumber": "string"
}, - "citizenship": "string",
- "embossedName1": "string",
- "embossedName2": "string",
- "firmOccupation": "string",
- "hasCompletedBiometrics": true,
- "isPep": true,
- "pepUnderstanding": "yes_i_do",
- "pepAcknowledgement": true,
- "hasAgreedToTerms": true,
- "hasAgreedToTariffs": true,
- "hasAgreedToCardholderLimitation": true,
- "hasAgreedToNoThirdPartyCards": true,
- "hasAgreedToCompanyLiability": true,
- "uboPepStatement": { }
}{- "success": true,
- "message": "string",
- "cardholderId": "string",
- "taskId": "string",
- "status": "PENDING"
}Returns the full IndividualOnboarding document plus the
resolved debit accounts (accounts), the active cards
(cards), and the live balances (balance). Same precedence as
the cardholder-side endpoints.
| id required | string Cardholder identifier (the |
| success | boolean |
object (IndividualOnboardingRecord) A cardholder onboarding record. | |
Array of objects (DebitAccount) | |
Array of objects (AccountCard) | |
| balance | number Live |
{- "success": true,
- "data": {
- "_id": "string",
- "origin": "API",
- "company": "string",
- "productVersion": [
- "string"
], - "personalInfo": {
- "firstName": "string",
- "middleName": "string",
- "lastName": "string",
- "mothersMaidenName": "string",
- "email": "string",
- "phoneNumber": "string",
- "phone": "string",
- "authPhoneNumber": "string",
- "birthDate": "2019-08-24T14:15:22Z",
- "birthCountry": "string",
- "dateOfBirth": "2019-08-24T14:15:22Z"
}, - "address": {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "city": "string",
- "stateProvince": "string",
- "zipCode": "string",
- "country": "string"
}, - "deliveryAddress": [
- {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "city": "string",
- "stateProvince": "string",
- "zipCode": "string",
- "country": "string",
- "_id": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
], - "idDocument": {
- "customerIdType": "PASSPORT",
- "number": "string",
- "issueDate": "2019-08-24T14:15:22Z",
- "expiryDate": "2019-08-24T14:15:22Z",
- "issuingCountry": "string",
- "frontImagePath": "string",
- "backImagePath": "string",
- "idAuthority": "string"
}, - "taxInfo": {
- "country": "string",
- "taxIdNumber": "string"
}, - "clientID": "string",
- "cardTypes": [
- "string"
], - "cardCurrency": [
- "string"
], - "client": true,
- "permissions": [
- "string"
], - "permissionAudit": [
- {
- "key": "string",
- "enabled": true
}
], - "permissionsLog": [
- { }
], - "legalId": "string",
- "firmOccupation": "string",
- "embossedName1": "string",
- "embossedName2": "string",
- "citizenship": "string",
- "riskLevel": 0,
- "riskStatus": "string",
- "operationStatus": "Active",
- "applicationId": "string",
- "applicationStatus": "PENDING",
- "applicationDate": "2019-08-24T14:15:22Z",
- "dashboardStatus": "ACTIVE",
- "userType": "b2b",
- "partner": "string",
- "b2bClient": "string",
- "isSelfAdmin": true,
- "createdOnBehalfOf": "string",
- "maxVirtualCards": 0,
- "maxPhysicalCards": 0,
- "hasCompletedBiometrics": true,
- "isPep": true,
- "pepUnderstanding": "yes_i_do",
- "pepAcknowledgement": true,
- "uboPepStatement": { },
- "hasAgreedToTerms": true,
- "hasAgreedToTariffs": true,
- "hasAgreedToCardholderLimitation": true,
- "hasAgreedToNoThirdPartyCards": true,
- "hasAgreedToCompanyLiability": true,
- "isPartnerIndividualProcessFinished": true,
- "orasysRequest": {
- "isAllOrasysAccountCreated": true,
- "createCustomerAccount": {
- "isCreated": true,
- "settlementCurrenciesCreated": [
- "string"
], - "requestCreateRetryCount": 0,
- "requestCreateErrors": [
- "string"
], - "requestGetRetryCount": 0,
- "requestGetErrors": [
- "string"
], - "createdAt": "2019-08-24T14:15:22Z",
- "requestCreateLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestGetLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestId": "string",
- "accountId": 0
}, - "createAccountType412100": {
- "isCreated": true,
- "settlementCurrenciesCreated": [
- "string"
], - "requestCreateRetryCount": 0,
- "requestCreateErrors": [
- "string"
], - "requestGetRetryCount": 0,
- "requestGetErrors": [
- "string"
], - "createdAt": "2019-08-24T14:15:22Z",
- "requestCreateLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestGetLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestId": "string",
- "accountId": 0
}, - "createAccountType412200": {
- "isCreated": true,
- "settlementCurrenciesCreated": [
- "string"
], - "requestCreateRetryCount": 0,
- "requestCreateErrors": [
- "string"
], - "requestGetRetryCount": 0,
- "requestGetErrors": [
- "string"
], - "createdAt": "2019-08-24T14:15:22Z",
- "requestCreateLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestGetLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestId": "string",
- "accountId": 0
}, - "createAccountType414000": {
- "isCreated": true,
- "settlementCurrenciesCreated": [
- "string"
], - "requestCreateRetryCount": 0,
- "requestCreateErrors": [
- "string"
], - "requestGetRetryCount": 0,
- "requestGetErrors": [
- "string"
], - "createdAt": "2019-08-24T14:15:22Z",
- "requestCreateLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestGetLastAttemptDate": "2019-08-24T14:15:22Z",
- "requestId": "string",
- "accountId": 0,
- "IBAN": "string"
}
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "__v": 0
}, - "accounts": [
- {
- "_id": "string",
- "owners": [
- {
- "clientCode": "string",
- "relationship": "OWN",
- "mainOwner": true,
- "_id": "string"
}
], - "b2bCompany": "string",
- "isCompany": true,
- "isB2b": true,
- "accountNumber": "string",
- "accountHolder": "string",
- "currencyCode": "string",
- "currency": "string",
- "status": "ACTIVE",
- "clientCode": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "__v": 0,
- "accountType": "string",
- "accountTypeSyncedAt": "2019-08-24T14:15:22Z"
}
], - "cards": [
- {
- "_id": "string",
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "cardType": "VIRTUAL",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string",
- "nickName": "string",
- "set_pin": true,
- "set_password": true,
- "authPhoneNumber": "string",
- "deliveryMethod": {
- "_id": "string",
- "deliveryType": "string",
- "pinDeliveryType": "LETTER",
- "methodFields": "string",
- "price": 0
}, - "cardMask": "string",
- "onboarding": "string",
- "b2bClient": "string",
- "isAdminBlocked": true,
- "deliveryAddress": {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "stateProvince": "string",
- "city": "string",
- "zipCode": "string",
- "country": "string"
}, - "limitOverrides": {
- "property1": {
- "defaultValue": 0,
- "maxValue": 0
}, - "property2": {
- "defaultValue": 0,
- "maxValue": 0
}
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "__v": 0
}
], - "balance": 0
}Returns every active card (AccountCard) under the cardholder.
Full-list response — no pagination.
| id required | string Cardholder |
| success | boolean |
| count | integer |
Array of objects (AccountCard) |
{- "success": true,
- "count": 0,
- "data": [
- {
- "_id": "string",
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "cardType": "VIRTUAL",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string",
- "nickName": "string",
- "set_pin": true,
- "set_password": true,
- "authPhoneNumber": "string",
- "deliveryMethod": {
- "_id": "string",
- "deliveryType": "string",
- "pinDeliveryType": "LETTER",
- "methodFields": "string",
- "price": 0
}, - "cardMask": "string",
- "onboarding": "string",
- "b2bClient": "string",
- "isAdminBlocked": true,
- "deliveryAddress": {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "stateProvince": "string",
- "city": "string",
- "zipCode": "string",
- "country": "string"
}, - "limitOverrides": {
- "property1": {
- "defaultValue": 0,
- "maxValue": 0
}, - "property2": {
- "defaultValue": 0,
- "maxValue": 0
}
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "__v": 0
}
]
}Resolves the IBANs the cardholder is allowed to issue against — the cardholder's own debit accounts plus any B2B-shared tenant accounts (if the cardholder is reusing company accounts).
| id required | string Cardholder |
| success | boolean |
| count | integer |
Array of objects (B2BIssuableIbanAccount) |
{- "success": true,
- "count": 0,
- "accounts": [
- {
- "_id": "string",
- "b2bAccountId": "string",
- "companyName": "string",
- "clientCode": "string",
- "accountNumber": "string",
- "currency": "string",
- "label": "string",
- "description": "string",
- "status": "string",
- "accountType": "string",
- "isActive": true,
- "isPrimary": true,
- "linkedCardsCount": 0,
- "activeCardsCount": 0,
- "createdAt": "2019-08-24T14:15:22Z"
}
]
}Issues a virtual card. The only required body field is
productCode — pick from the tenant's products via
GET /business/accounts/{b2bAccountId}/products. Pass
accNo to override which IBAN funds the card; otherwise the
cardholder's first eligible IBAN is used. Embossed-name fields
and currency default from the cardholder record.
| id required | string Cardholder |
| Idempotency-Key | string <uuid> Example: 550e8400-e29b-41d4-a716-446655440000 Optional idempotency key to ensure safe retries for non-GET requests. When provided, the API remembers your request and returns the exact same result if the same key is sent within 60 seconds. This protects against duplicate operations in case of network timeouts or accidental retries. Recommended: Use a UUID v4 for each logical operation. Response headers:
|
| productCode required | string Product code of one of the tenant's products
( |
| accNo | string Optional IBAN to draw funding from. If omitted, the
cardholder's first eligible IBAN is used. Use
|
| success required | boolean |
| message required | string |
required | object (PartnerVirtualIssuedCard) Slim card shape returned by the partner-individual virtual-card
creation endpoint ( The card-issuing platform's virtual-card creation response
carries only these. Lifecycle / shipping fields
( |
{- "productCode": "R004",
- "accNo": "string"
}{- "success": true,
- "message": "Virtual card created successfully",
- "data": {
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "cardType": "VIRTUAL",
- "kind": "DEBIT",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "cardMask": "string",
- "onboarding": "string"
}
}Issues a physical card against one of the cardholder's eligible
IBANs. deliveryMethod is required (use
GET /fees/delivery-methods to discover the available
_ids). phoneNumber and country are required for the
delivery address; embossName1 overrides the cardholder default.
| id required | string Cardholder |
| Idempotency-Key | string <uuid> Example: 550e8400-e29b-41d4-a716-446655440000 Optional idempotency key to ensure safe retries for non-GET requests. When provided, the API remembers your request and returns the exact same result if the same key is sent within 60 seconds. This protects against duplicate operations in case of network timeouts or accidental retries. Recommended: Use a UUID v4 for each logical operation. Response headers:
|
| productCode required | string |
required | object Delivery method chosen from
|
| phoneNumber | string Delivery contact phone. |
| country | string ISO 3166-1 alpha-3 country code for the delivery address. |
| embossName1 | string Optional override for the card's primary embossed name. |
| success required | boolean |
| message required | string |
required | object (PartnerPhysicalIssuedCard) Full card shape returned by the partner-individual physical-card
creation endpoint ( Mirrors the full |
{- "productCode": "R003",
- "deliveryMethod": {
- "_id": "pp_poczta-6836df4c98653594cae54d72",
- "deliveryType": "LETTER",
- "pinDeliveryType": "LETTER",
- "methodFields": "string",
- "price": 0
}, - "phoneNumber": "string",
- "country": "BGR",
- "embossName1": "string"
}{- "success": true,
- "message": "Physical card created successfully",
- "data": {
- "_id": "string",
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "cardType": "VIRTUAL",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string",
- "nickName": "string",
- "set_pin": true,
- "set_password": true,
- "authPhoneNumber": "string",
- "deliveryMethod": {
- "_id": "string",
- "deliveryType": "string",
- "pinDeliveryType": "LETTER",
- "methodFields": "string",
- "price": 0
}, - "cardMask": "string",
- "onboarding": "string",
- "b2bClient": "string",
- "isAdminBlocked": true,
- "deliveryAddress": {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "stateProvince": "string",
- "city": "string",
- "zipCode": "string",
- "country": "string"
}, - "limitOverrides": {
- "property1": {
- "defaultValue": 0,
- "maxValue": 0
}, - "property2": {
- "defaultValue": 0,
- "maxValue": 0
}
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "__v": 0
}
}Requests a prepaid virtual card. The card is not created in this
call. The call checks the request and answers 200 with
status: "PENDING". The card is created in the background, usually
within 2-3 minutes, and then appears in the card list of the cardholder.
The body is optional. productCode can only be R008 (the default),
and the currency is EUR.
A request that is not valid (for example a product that is not assigned
to the company) is refused with 400 before anything is requested.
| id required | string Cardholder |
| Idempotency-Key | string <uuid> Example: 550e8400-e29b-41d4-a716-446655440000 Optional idempotency key to ensure safe retries for non-GET requests. When provided, the API remembers your request and returns the exact same result if the same key is sent within 60 seconds. This protects against duplicate operations in case of network timeouts or accidental retries. Recommended: Use a UUID v4 for each logical operation. Response headers:
|
| productCode | string Default: "R008" Value: "R008" The prepaid virtual card product. Only |
| currencyCode | string Default: "EUR" Value: "EUR" Currency of the card. Only |
| nickname | string Optional card nickname. |
| message | string |
object |
{- "nickname": "Online shopping"
}{- "message": "Prepaid physical card requested. The card will be created in a few minutes (2-3 minutes).",
- "data": {
- "prepaidRequestId": "6840a1f2c3d4e5f6a7b8c9d0",
- "cardKind": "physical",
- "cardholderId": "6836df4c98653594cae54d72",
- "productCode": "R007",
- "currency": "EUR",
- "status": "PENDING"
}
}Requests a prepaid physical card. The card is not created in this
call. The call checks the request and answers 200 with
status: "PENDING". The card is created in the background, usually
within 2-3 minutes, and then appears in the card list of the cardholder.
deliveryMethod._id (use GET /fees/delivery-methods to find it),
phoneNumber, country and embossName1 are required. productCode
can only be R007 (the default). The card issuing fee and the delivery
fee are blocked on the main account when you call this endpoint
(debitAccountNumber, or the default main account), and are charged
when the card is created. If the card cannot be created, the fees are
unblocked. If the main account does not have enough money, the call is
refused with 400. The card limit for prepaid physical cards is
separate from the limit of normal physical cards.
A request that is not valid (for example a product that is not assigned
to the company) is refused with 400 before anything is requested.
| id required | string Cardholder |
| Idempotency-Key | string <uuid> Example: 550e8400-e29b-41d4-a716-446655440000 Optional idempotency key to ensure safe retries for non-GET requests. When provided, the API remembers your request and returns the exact same result if the same key is sent within 60 seconds. This protects against duplicate operations in case of network timeouts or accidental retries. Recommended: Use a UUID v4 for each logical operation. Response headers:
|
| productCode | string Default: "R007" Value: "R007" The prepaid physical card product. Only |
required | object How the card is sent (carrier). Take the The carrier is read from the start of |
| phoneNumber required | string Delivery contact phone. |
| country required | string ISO 3166-1 alpha-3 country code. Used for the delivery fee (EEA vs non-EEA) when
|
| deliveryAddressId | string Where the card is sent: a saved address of the cardholder. When it is left out, the
card goes to the cardholder's registered address and the fee uses |
| embossName1 required | string <= 22 characters First line of text embossed on the card. |
| embossName2 | string <= 19 characters Optional second line of text embossed on the card. |
| nickname | string Optional card nickname. |
| debitAccountNumber | string <= 34 characters The MAIN account (IBAN) the issuing and delivery fees are charged from. It must belong to
the cardholder (or to the company of a B2B cardholder), otherwise the request is refused
with |
| message | string |
object |
{- "productCode": "R007",
- "nickname": "Travel card",
- "deliveryMethod": {
- "_id": "pp_poczta-6836df4c98653594cae54d72"
}, - "phoneNumber": "+359888123456",
- "country": "BGR",
- "deliveryAddressId": "onboarding:6836df4c98653594cae54d99",
- "embossName1": "ANA IVANOVA",
- "embossName2": "ACME LTD",
- "debitAccountNumber": "XX00XXXX0000000000000000"
}{- "message": "Prepaid physical card requested. The card will be created in a few minutes (2-3 minutes).",
- "data": {
- "prepaidRequestId": "6840a1f2c3d4e5f6a7b8c9d0",
- "cardKind": "physical",
- "cardholderId": "6836df4c98653594cae54d72",
- "productCode": "R007",
- "currency": "EUR",
- "status": "PENDING"
}
}Returns the prepaid card requests of the cardholder, newest first, one page at a time (page and
limit, up to 100 per page). A prepaid card is created in the background, so use this to see where
each request is. Every item has a status and an isFinished flag. pagination tells whether
there are more pages. A page or limit that is not a positive whole number is a 400.
| id required | string Cardholder |
| page | integer >= 1 Default: 1 Example: page=1 Page number for pagination. Starts at |
| limit | integer [ 1 .. 100 ] Default: 100 Example: limit=20 Number of prepaid card requests per page. At most |
| sortBy | string Default: "createdAt" Value: "createdAt" Field to sort by. Only |
| sortOrder | string Default: "desc" Enum: "desc" "asc"
|
| count | integer Number of requests on this page. |
Array of objects (PrepaidCardRequestStatus) | |
object (Pagination) |
{- "count": 0,
- "data": [
- {
- "prepaidRequestId": "6840a1f2c3d4e5f6a7b8c9d0",
- "cardKind": "physical",
- "cardholderId": "6836df4c98653594cae54d72",
- "productCode": "R007",
- "currency": "EUR",
- "status": "PENDING",
- "isFinished": false,
- "statusMessage": "The card is being created. This usually takes 2-3 minutes.",
- "cardKey": null,
- "feesReleased": false,
- "createdAt": "2026-10-08T10:15:00.000Z",
- "statusUpdatedAt": "2026-10-08T10:17:10.000Z"
}
], - "pagination": {
- "page": 0,
- "limit": 0,
- "total": 0,
- "pages": 0,
- "hasNextPage": true,
- "hasPrevPage": true
}
}Returns where one prepaid card request is. Ask again every few seconds until isFinished is
true. When status is SUCCESS, cardKey is the key of the new card. When it is FAILED,
contact PayNovus support and give the prepaidRequestId; statusMessage says so.
A request that does not exist, or belongs to another cardholder, is a 404.
| id required | string Cardholder |
| requestId required | string The |
object (PrepaidCardRequestStatus) Where one prepaid card request is. | |||||||||||||||||||||||||
| |||||||||||||||||||||||||
{- "data": {
- "prepaidRequestId": "6840a1f2c3d4e5f6a7b8c9d0",
- "cardKind": "physical",
- "cardholderId": "6836df4c98653594cae54d72",
- "productCode": "R007",
- "currency": "EUR",
- "status": "PENDING",
- "isFinished": false,
- "statusMessage": "The card is being created. This usually takes 2-3 minutes.",
- "cardKey": null,
- "feesReleased": false,
- "createdAt": "2026-10-08T10:15:00.000Z",
- "statusUpdatedAt": "2026-10-08T10:17:10.000Z"
}
}Endpoints for managing individual cardholders onboarded by the partner. All paths under this tag are scoped to the calling partner.
Returns every individual onboarding owned by the authenticated partner
in a single response. This endpoint does not paginate. The payload
includes a count field and the full data array.
| count | integer |
Array of objects (IndividualAccountSummary) |
{- "count": 0,
- "data": [
- {
- "_id": "string",
- "clientID": "string",
- "personalInfo": {
- "firstName": "string",
- "middleName": "string",
- "lastName": "string",
- "email": "user@example.com",
- "phoneNumber": "string",
- "birthDate": "2019-08-24T14:15:22Z",
- "birthCountry": "string",
- "authPhoneNumber": "string"
}, - "address": {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "city": "string",
- "stateProvince": "string",
- "zipCode": "string",
- "country": "string"
}, - "applicationStatus": "PENDING",
- "dashboardStatus": "ACTIVE",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
]
}Creates a partner-owned individual cardholder. The individual never logs into the CIP dashboard — the partner has its own dashboard for that; the record exists here only so PayNovus admins can see and control it on the partner's behalf.
| Idempotency-Key | string <uuid> Example: 550e8400-e29b-41d4-a716-446655440000 Optional idempotency key to ensure safe retries for non-GET requests. When provided, the API remembers your request and returns the exact same result if the same key is sent within 60 seconds. This protects against duplicate operations in case of network timeouts or accidental retries. Recommended: Use a UUID v4 for each logical operation. Response headers:
|
| firstName required | string <= 200 characters |
| middleName required | string [ 2 .. 200 ] characters |
| lastName required | string <= 200 characters |
| country required | string = 2 characters ISO 3166-1 alpha-2 country code |
| city required | string <= 100 characters |
| stateProvince | string <= 100 characters Optional state / province / region. |
| zipCode required | string <= 20 characters |
| buildingNumber required | string <= 100 characters |
| idType required | string Enum: "PASSPORT" "DRIVER_LICENSE" "RESIDENCE_CARD" "MINOR_WITHOUT_ID" "OTHER" |
| address1 required | string <= 200 characters |
| address2 | string <= 200 characters Optional secondary address line. |
| passportNumber required | string <= 40 characters |
| issuingDate required | string Document issue date in |
| validityDate required | string Document expiry date in |
| passportCountry required | string = 2 characters ISO 3166-1 alpha-2 country code that issued the document |
| taxCountry | string = 2 characters Optional ISO 3166-1 alpha-2 country code for tax residency. Must be exactly 2 letters if provided. |
| taxIdNumber | string <= 40 characters Optional tax identification number. Defaults to |
| birthCountry required | string = 2 characters |
| birthDate required | string yyyy-mm-dd |
| nationality required | string = 2 characters |
| phone required | string [ 10 .. 20 ] characters |
| email required | string <email> <= 100 characters |
| message required | string Human-readable success message. |
| individualId required | string Mongo |
{- "firstName": "Casey",
- "middleName": "Quinn",
- "lastName": "Sample",
- "country": "PL",
- "city": "Samplecity",
- "stateProvince": "Sampleregion",
- "zipCode": "00-000",
- "buildingNumber": "0",
- "idType": "PASSPORT",
- "address1": "Sample Street 0",
- "passportNumber": "X0000000",
- "issuingDate": "2020-01-01",
- "validityDate": "2030-01-01",
- "passportCountry": "PL",
- "taxCountry": "PL",
- "taxIdNumber": "0000000000",
- "birthCountry": "PL",
- "birthDate": "1990-01-01",
- "nationality": "PL",
- "phone": "+10000000000",
- "email": "partner.example@example.com"
}{- "message": "Individual account created successfully",
- "individualId": "string"
}Returns the individual onboarding identified by :id. The record
must be owned by your partner — otherwise the response is
404 Not Found (no enumeration).
For B2B tenants, cardholders live under the tenant and are listed
at GET /business/accounts/{b2bAccountId}/cardholders. Each B2B
cardholder can also be inspected individually by id via the
cardholder page at GET /business/cardholders/{id} — useful when
you already have a cardholder id and want the full onboarding
document without re-listing the tenant.
| id required | string Individual identifier |
| message | string |
object (IndividualAccount) Flat partner-facing individual account view returned by | |
Array of objects (AccountCard) | |
| balance | number Live |
{- "message": "string",
- "accounts": {
- "_id": "string",
- "email": "user@example.com",
- "firstName": "string",
- "middleName": "string",
- "lastName": "string",
- "phone": "string",
- "birthDate": "2019-08-24T14:15:22Z",
- "birthCountry": "string",
- "country": "string",
- "city": "string",
- "stateProvince": "string",
- "zipCode": "string",
- "buildingNumber": "string",
- "address1": "string",
- "address2": "string",
- "idType": "PASSPORT",
- "passportNumber": "string",
- "issuingDate": "2019-08-24T14:15:22Z",
- "validityDate": "2019-08-24T14:15:22Z",
- "passportCountry": "string",
- "taxCountry": "string",
- "taxIdNumber": "string",
- "nationality": "string",
- "IBAN": "string"
}, - "cards": [
- {
- "_id": "string",
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "cardType": "VIRTUAL",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string",
- "nickName": "string",
- "set_pin": true,
- "set_password": true,
- "authPhoneNumber": "string",
- "deliveryMethod": {
- "_id": "string",
- "deliveryType": "string",
- "pinDeliveryType": "LETTER",
- "methodFields": "string",
- "price": 0
}, - "cardMask": "string",
- "onboarding": "string",
- "b2bClient": "string",
- "isAdminBlocked": true,
- "deliveryAddress": {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "stateProvince": "string",
- "city": "string",
- "zipCode": "string",
- "country": "string"
}, - "limitOverrides": {
- "property1": {
- "defaultValue": 0,
- "maxValue": 0
}, - "property2": {
- "defaultValue": 0,
- "maxValue": 0
}
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "__v": 0
}
], - "balance": 0
}Returns every active card owned by the given individual in one
response. This endpoint does not paginate and returns { count, data }.
| id required | string Individual onboarding |
| count | integer Number of cards in |
Array of objects (AccountCard) |
{- "count": 0,
- "data": [
- {
- "_id": "string",
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "cardType": "VIRTUAL",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string",
- "nickName": "string",
- "set_pin": true,
- "set_password": true,
- "authPhoneNumber": "string",
- "deliveryMethod": {
- "_id": "string",
- "deliveryType": "string",
- "pinDeliveryType": "LETTER",
- "methodFields": "string",
- "price": 0
}, - "cardMask": "string",
- "onboarding": "string",
- "b2bClient": "string",
- "isAdminBlocked": true,
- "deliveryAddress": {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "stateProvince": "string",
- "city": "string",
- "zipCode": "string",
- "country": "string"
}, - "limitOverrides": {
- "property1": {
- "defaultValue": 0,
- "maxValue": 0
}, - "property2": {
- "defaultValue": 0,
- "maxValue": 0
}
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "__v": 0
}
]
}Returns the live availableBalance for each IBAN linked to the
individual.
Per-IBAN failure handling. Any IBAN whose balance cannot be
resolved is surfaced in the response with status: "error" and
an errorMessage field — failures are never silently
reported as zero. The overall HTTP status remains 200 so a
partner UI can still render the IBANs that succeeded.
| id required | string Individual identifier — must be owned by the calling partner. |
| success | boolean |
| count | integer |
Array of objects (BalanceEntry) |
{- "success": true,
- "count": 0,
- "data": [
- {
- "iban": "string",
- "availableBalance": 0,
- "currency": "string",
- "accountHolder": "string",
- "isB2bShared": true,
- "accountStatus": "string",
- "status": "ok",
- "errorMessage": "string"
}
]
}Issues a virtual card under the given individual. The card is created on the partner/individual ownership chain.
The request body is optional. Every field has a sensible
server-side default — omitting the body entirely issues a card
with the cardholder's primary IBAN, currency, and the default
virtual-card product (R002). Pass any subset of the fields
below to override individual defaults; embossName1,
embossName2, currencyCode, accNo, and productCode are all
optional.
| id required | string |
| Idempotency-Key | string <uuid> Example: 550e8400-e29b-41d4-a716-446655440000 Optional idempotency key to ensure safe retries for non-GET requests. When provided, the API remembers your request and returns the exact same result if the same key is sent within 60 seconds. This protects against duplicate operations in case of network timeouts or accidental retries. Recommended: Use a UUID v4 for each logical operation. Response headers:
|
| embossName1 | string <= 22 characters First line of text embossed on the card. |
| currencyCode | integer Numeric ISO 4217 currency code. Falls back to the cardholder's debit-account currency when omitted. |
| accNo | string IBAN to link the card to. Falls back to the cardholder's primary account when omitted. |
| productCode | string Product code. Defaults to |
| success required | boolean |
| message required | string |
required | object (PartnerVirtualIssuedCard) Slim card shape returned by the partner-individual virtual-card
creation endpoint ( The card-issuing platform's virtual-card creation response
carries only these. Lifecycle / shipping fields
( |
{- "embossName1": "CASEY SAMPLE",
- "currencyCode": 978,
- "accNo": "XX00XXXX0000000000000000",
- "productCode": "R002"
}{- "success": true,
- "message": "Virtual card created successfully",
- "data": {
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "cardType": "VIRTUAL",
- "kind": "DEBIT",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "cardMask": "string",
- "onboarding": "string"
}
}Issues a physical card under the given individual.
Only deliveryMethod._id is required. The other
deliveryMethod fields and productCode, embossName1,
embossName2, nickname, currencyCode, accNo, and country
are all optional — pass any subset to override individual
defaults; omit the body entirely (except deliveryMethod._id)
and the cardholder's stored values are used.
| id required | string |
| Idempotency-Key | string <uuid> Example: 550e8400-e29b-41d4-a716-446655440000 Optional idempotency key to ensure safe retries for non-GET requests. When provided, the API remembers your request and returns the exact same result if the same key is sent within 60 seconds. This protects against duplicate operations in case of network timeouts or accidental retries. Recommended: Use a UUID v4 for each logical operation. Response headers:
|
| productCode | string Product code. Defaults to |
| embossName1 | string <= 22 characters First line of text embossed on the card. Defaults to the cardholder's stored |
| embossName2 | string <= 19 characters Second line of text embossed on the card. Defaults to the cardholder's stored |
| nickname | string Optional card nickname shown in the partner/individual UI. |
object Delivery method for the physical card. The accepted prefixes are
| |
| currencyCode | integer Numeric ISO 4217 currency code. Falls back to the resolved debit account currency when omitted. |
| accNo | string IBAN to link the card to. Falls back to the cardholder's primary account when omitted. |
| country | string ISO 3166-1 country code (alpha-2 or alpha-3) for the delivery destination. Optional — defaults to the cardholder's country. |
| success required | boolean |
| message required | string |
required | object (PartnerPhysicalIssuedCard) Full card shape returned by the partner-individual physical-card
creation endpoint ( Mirrors the full |
{- "productCode": "R001",
- "embossName1": "CASEY SAMPLE",
- "embossName2": "string",
- "nickname": "string",
- "deliveryMethod": {
- "_id": "pp_poczta-000000000000000000000000",
- "deliveryType": "LETTER",
- "pinDeliveryType": "LETTER",
- "methodFields": "Poczta_Post 100g",
- "price": 0
}, - "currencyCode": 978,
- "accNo": "XX00XXXX0000000000000000",
- "country": "BGR"
}{- "success": true,
- "message": "Physical card created successfully",
- "data": {
- "_id": "string",
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "cardType": "VIRTUAL",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string",
- "nickName": "string",
- "set_pin": true,
- "set_password": true,
- "authPhoneNumber": "string",
- "deliveryMethod": {
- "_id": "string",
- "deliveryType": "string",
- "pinDeliveryType": "LETTER",
- "methodFields": "string",
- "price": 0
}, - "cardMask": "string",
- "onboarding": "string",
- "b2bClient": "string",
- "isAdminBlocked": true,
- "deliveryAddress": {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "stateProvince": "string",
- "city": "string",
- "zipCode": "string",
- "country": "string"
}, - "limitOverrides": {
- "property1": {
- "defaultValue": 0,
- "maxValue": 0
}, - "property2": {
- "defaultValue": 0,
- "maxValue": 0
}
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "__v": 0
}
}Requests a prepaid virtual card. The card is not created in this
call. The call checks the request and answers 200 with
status: "PENDING". The card is created in the background, usually
within 2-3 minutes, and then appears in the card list of the cardholder.
The body is optional. productCode can only be R008 (the default),
and the currency is EUR.
A request that is not valid (for example a product that is not assigned
to the company) is refused with 400 before anything is requested.
| id required | string Individual |
| Idempotency-Key | string <uuid> Example: 550e8400-e29b-41d4-a716-446655440000 Optional idempotency key to ensure safe retries for non-GET requests. When provided, the API remembers your request and returns the exact same result if the same key is sent within 60 seconds. This protects against duplicate operations in case of network timeouts or accidental retries. Recommended: Use a UUID v4 for each logical operation. Response headers:
|
| productCode | string Default: "R008" Value: "R008" The prepaid virtual card product. Only |
| currencyCode | string Default: "EUR" Value: "EUR" Currency of the card. Only |
| nickname | string Optional card nickname. |
| message | string |
object |
{- "nickname": "Online shopping"
}{- "message": "Prepaid physical card requested. The card will be created in a few minutes (2-3 minutes).",
- "data": {
- "prepaidRequestId": "6840a1f2c3d4e5f6a7b8c9d0",
- "cardKind": "physical",
- "cardholderId": "6836df4c98653594cae54d72",
- "productCode": "R007",
- "currency": "EUR",
- "status": "PENDING"
}
}Requests a prepaid physical card. The card is not created in this
call. The call checks the request and answers 200 with
status: "PENDING". The card is created in the background, usually
within 2-3 minutes, and then appears in the card list of the cardholder.
deliveryMethod._id (use GET /fees/delivery-methods to find it),
phoneNumber, country and embossName1 are required. productCode
can only be R007 (the default). The card issuing fee and the delivery
fee are blocked on the main account when you call this endpoint
(debitAccountNumber, or the default main account), and are charged
when the card is created. If the card cannot be created, the fees are
unblocked. If the main account does not have enough money, the call is
refused with 400. The card limit for prepaid physical cards is
separate from the limit of normal physical cards.
A request that is not valid (for example a product that is not assigned
to the company) is refused with 400 before anything is requested.
| id required | string Individual |
| Idempotency-Key | string <uuid> Example: 550e8400-e29b-41d4-a716-446655440000 Optional idempotency key to ensure safe retries for non-GET requests. When provided, the API remembers your request and returns the exact same result if the same key is sent within 60 seconds. This protects against duplicate operations in case of network timeouts or accidental retries. Recommended: Use a UUID v4 for each logical operation. Response headers:
|
| productCode | string Default: "R007" Value: "R007" The prepaid physical card product. Only |
required | object How the card is sent (carrier). Take the The carrier is read from the start of |
| phoneNumber required | string Delivery contact phone. |
| country required | string ISO 3166-1 alpha-3 country code. Used for the delivery fee (EEA vs non-EEA) when
|
| deliveryAddressId | string Where the card is sent: a saved address of the cardholder. When it is left out, the
card goes to the cardholder's registered address and the fee uses |
| embossName1 required | string <= 22 characters First line of text embossed on the card. |
| embossName2 | string <= 19 characters Optional second line of text embossed on the card. |
| nickname | string Optional card nickname. |
| debitAccountNumber | string <= 34 characters The MAIN account (IBAN) the issuing and delivery fees are charged from. It must belong to
the cardholder (or to the company of a B2B cardholder), otherwise the request is refused
with |
| message | string |
object |
{- "productCode": "R007",
- "nickname": "Travel card",
- "deliveryMethod": {
- "_id": "pp_poczta-6836df4c98653594cae54d72"
}, - "phoneNumber": "+359888123456",
- "country": "BGR",
- "deliveryAddressId": "onboarding:6836df4c98653594cae54d99",
- "embossName1": "ANA IVANOVA",
- "embossName2": "ACME LTD",
- "debitAccountNumber": "XX00XXXX0000000000000000"
}{- "message": "Prepaid physical card requested. The card will be created in a few minutes (2-3 minutes).",
- "data": {
- "prepaidRequestId": "6840a1f2c3d4e5f6a7b8c9d0",
- "cardKind": "physical",
- "cardholderId": "6836df4c98653594cae54d72",
- "productCode": "R007",
- "currency": "EUR",
- "status": "PENDING"
}
}Returns the prepaid card requests of the cardholder, newest first, one page at a time (page and
limit, up to 100 per page). A prepaid card is created in the background, so use this to see where
each request is. Every item has a status and an isFinished flag. pagination tells whether
there are more pages. A page or limit that is not a positive whole number is a 400.
| id required | string Individual |
| page | integer >= 1 Default: 1 Example: page=1 Page number for pagination. Starts at |
| limit | integer [ 1 .. 100 ] Default: 100 Example: limit=20 Number of prepaid card requests per page. At most |
| sortBy | string Default: "createdAt" Value: "createdAt" Field to sort by. Only |
| sortOrder | string Default: "desc" Enum: "desc" "asc"
|
| count | integer Number of requests on this page. |
Array of objects (PrepaidCardRequestStatus) | |
object (Pagination) |
{- "count": 0,
- "data": [
- {
- "prepaidRequestId": "6840a1f2c3d4e5f6a7b8c9d0",
- "cardKind": "physical",
- "cardholderId": "6836df4c98653594cae54d72",
- "productCode": "R007",
- "currency": "EUR",
- "status": "PENDING",
- "isFinished": false,
- "statusMessage": "The card is being created. This usually takes 2-3 minutes.",
- "cardKey": null,
- "feesReleased": false,
- "createdAt": "2026-10-08T10:15:00.000Z",
- "statusUpdatedAt": "2026-10-08T10:17:10.000Z"
}
], - "pagination": {
- "page": 0,
- "limit": 0,
- "total": 0,
- "pages": 0,
- "hasNextPage": true,
- "hasPrevPage": true
}
}Returns where one prepaid card request is. Ask again every few seconds until isFinished is
true. When status is SUCCESS, cardKey is the key of the new card. When it is FAILED,
contact PayNovus support and give the prepaidRequestId; statusMessage says so.
A request that does not exist, or belongs to another cardholder, is a 404.
| id required | string Individual |
| requestId required | string The |
object (PrepaidCardRequestStatus) Where one prepaid card request is. | |||||||||||||||||||||||||
| |||||||||||||||||||||||||
{- "data": {
- "prepaidRequestId": "6840a1f2c3d4e5f6a7b8c9d0",
- "cardKind": "physical",
- "cardholderId": "6836df4c98653594cae54d72",
- "productCode": "R007",
- "currency": "EUR",
- "status": "PENDING",
- "isFinished": false,
- "statusMessage": "The card is being created. This usually takes 2-3 minutes.",
- "cardKey": null,
- "feesReleased": false,
- "createdAt": "2026-10-08T10:15:00.000Z",
- "statusUpdatedAt": "2026-10-08T10:17:10.000Z"
}
}Returns the audit log entries scoped to the given individual.
This endpoint is paginated. The default is page=1 and limit=50.
There is currently no hard server-side cap on the limit value in the
Partner API implementation. The response contains data and a
pagination object with total, page, limit, and pages.
Filters can be combined: ?action=LOCK_CARD&result=SUCCESS&from=2025-01-01.
| id required | string |
| page | integer >= 1 Default: 1 Example: page=1 Page number for pagination. Starts at |
| limit | integer >= 1 Default: 50 Example: limit=50 Number of audit-log or card-status-history records to return per
page. Defaults to |
| from | string <date-time> Inclusive lower bound on the entry's |
| to | string <date-time> Inclusive upper bound on the entry's |
| sort | string Sort order, comma-separated |
| cardId | string Filter by card |
| action | string Filter by action name (e.g. |
| result | string Enum: "SUCCESS" "FAILED" Filter by outcome. |
| success | boolean |
Array of objects (AuditLogEntry) | |
object (Pagination) |
{- "success": true,
- "data": [
- {
- "_id": "string",
- "logRequestId": "string",
- "userId": "string",
- "partnerId": "string",
- "customerId": "string",
- "cardId": "string",
- "b2bAccountId": "string",
- "targetUserId": "string",
- "eventTaskId": "string",
- "entityType": "string",
- "entityId": "string",
- "ipAddress": "string",
- "action": "CREATE_VIRTUAL_CARD",
- "result": "SUCCESS",
- "oldData": { },
- "newData": { },
- "errorMessage": null,
- "createdAt": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "page": 0,
- "limit": 0,
- "total": 0,
- "pages": 0,
- "hasNextPage": true,
- "hasPrevPage": true
}
}Returns every card-status change recorded for this individual.
This endpoint is paginated. The default is page=1 and limit=50.
There is currently no hard server-side cap on the limit value in the
Partner API implementation. The response contains data and a
pagination object with total, page, limit, and pages.
Filters can be combined: ?fromStatus=ACTIVE&toStatus=LOCKED&triggeredBy=PARTNER.
| id required | string |
| page | integer >= 1 Default: 1 Example: page=1 Page number for pagination. Starts at |
| limit | integer >= 1 Default: 50 Example: limit=50 Number of audit-log or card-status-history records to return per
page. Defaults to |
| from | string <date-time> Inclusive lower bound on the entry's |
| to | string <date-time> Inclusive upper bound on the entry's |
| sort | string Sort order, comma-separated |
| cardId | string Filter by card |
| fromStatus | string Filter by the card status before the change. Accepts either the
status name (e.g. |
| toStatus | string Filter by the card status after the change. Accepts either the
status name (e.g. |
| triggeredBy | string Enum: "PARTNER" "USER" "SYSTEM" Filter by who drove the status change. |
| triggeredByUserId | string Filter by the dashboard user that drove the change (only set when
|
Array of objects (CardStatusHistoryEntryRaw) | |
object (Pagination) |
{- "data": [
- {
- "_id": "string",
- "logRequestId": "string",
- "cardId": "string",
- "customerId": "string",
- "fromStatus": "ACTIVE",
- "toStatus": "ACTIVE",
- "triggeredBy": "PARTNER",
- "triggeredByUserId": "string",
- "triggeredByPartnerId": "string",
- "ipAddress": "string",
- "createdAt": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "page": 0,
- "limit": 0,
- "total": 0,
- "pages": 0,
- "hasNextPage": true,
- "hasPrevPage": true
}
}Paginated transactions for the individual. Defaults: page=1,
limit=10. No hard server-side cap on limit.
The response contains transactions and a provider pagination
object.
| id required | string |
| page | integer >= 1 Default: 1 Example: page=1 Page number for pagination. Starts at |
| limit | integer >= 1 Default: 10 Example: limit=10 Number of transactions to return per page. Defaults to |
Array of objects (Transaction) | |
object |
{- "transactions": [
- {
- "transactionProcessingCode": "string",
- "transactionAmount": 0,
- "billingAmount": 0,
- "transactionDatetime": "string",
- "localTransactionTime": "2019-08-24T14:15:22Z",
- "conversionRate": "string",
- "traceNumber": "string",
- "cardExpiryDate": "string",
- "retrievalReference": "string",
- "terminalId": "string",
- "merchantId": "string",
- "merchantLocation": "string",
- "cardId": "string",
- "currencyTransaction": "string",
- "currencyBilling": "string",
- "accountIdentification": "string",
- "customFields": {
- "transactionInfo": "string",
- "paypalReference": "string"
}, - "extendedData": {
- "authorizationLevel": "string",
- "authorizationMethod": "string",
- "productCode": "string",
- "deviceId": "string",
- "channelId": "string",
- "riskScore": "string",
- "retryCount": "string",
- "trackingId": "string"
}, - "resolvent": {
- "type": "denied",
- "resolved": true,
- "date": "2019-08-24T14:15:22Z"
}, - "processingOutcome": {
- "approved": true,
- "declineReasonCode": "string"
}, - "fees": {
- "taxType": "string",
- "taxAmount": 0,
- "taxAmountFx": 0,
- "taxNarrative": "string"
}, - "externalToken": "string",
- "transType": {
- "codeOraSys": "string",
- "description": "string",
- "action": "DR",
- "directionType": "D",
- "ryvylLabel": "string",
- "ryvylStatement": "string",
- "mcc": "string",
- "settlementCode": "string"
}, - "transStatus": "pending",
- "createdAt": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "total": 0,
- "page": 0,
- "limit": 0,
- "totalPages": 0
}
}Partner-wide transaction history aggregation. Endpoints under this tag scope their results to the calling partner — the partner physically cannot see another partner's transactions, and ownership-mismatch responses use a non-enumerating 404 envelope rather than 403.
Returns every transaction the authenticated partner is allowed to see, aggregated across all of its linked individual onboardings (and any B2B-shared tenant accounts that those onboardings resolve to).
This endpoint is paginated. The default is page=1 and limit=10.
There is currently no hard server-side cap on limit.
Pass the values as query parameters, for example
?page=2&limit=3000. The response contains the transaction data
and pagination metadata including the total number of matching
rows and total pages.
Filter rules. The two filters are mutually exclusive — passing both at once returns 400:
?accountIdentification=… — narrow to one or more IBANs.
Accepts a single IBAN, a comma-separated list
(?accountIdentification=DE1,DE2), or repeated keys
(?accountIdentification=DE1&accountIdentification=DE2). Any
IBAN the partner does not own is silently excluded from the
result. If every supplied IBAN is foreign to the partner, the
endpoint returns 404 "IBAN not found."?cardId=<cardKey> — narrow to a single card. Exactly one
cardKey is allowed; passing multiple (repeated keys or
comma-separated) returns 400. An unowned cardKey returns
404 "Card not found!".When neither filter is supplied, the partner's full owned-IBAN union is queried. If the partner has zero owned IBANs the endpoint returns 400.
Empty result sets (no rows in the date range) are returned with
HTTP 200 and an empty data array — mirroring
/individual/accounts/{id}/transactions.
| page | integer >= 1 Default: 1 Example: page=1 Page number for pagination. Starts at |
| limit | integer >= 1 Default: 10 Example: limit=10 Number of transactions to return per page. Defaults to |
| accountIdentification | string One IBAN, or several (comma-separated, or repeated keys).
Only IBANs the partner owns are forwarded; foreign IBANs are
silently excluded. Mutually exclusive with |
| cardId | string Single card |
Array of objects (Transaction) | |
object |
{- "transactions": [
- {
- "transactionProcessingCode": "string",
- "transactionAmount": 0,
- "billingAmount": 0,
- "transactionDatetime": "string",
- "localTransactionTime": "2019-08-24T14:15:22Z",
- "conversionRate": "string",
- "traceNumber": "string",
- "cardExpiryDate": "string",
- "retrievalReference": "string",
- "terminalId": "string",
- "merchantId": "string",
- "merchantLocation": "string",
- "cardId": "string",
- "currencyTransaction": "string",
- "currencyBilling": "string",
- "accountIdentification": "string",
- "customFields": {
- "transactionInfo": "string",
- "paypalReference": "string"
}, - "extendedData": {
- "authorizationLevel": "string",
- "authorizationMethod": "string",
- "productCode": "string",
- "deviceId": "string",
- "channelId": "string",
- "riskScore": "string",
- "retryCount": "string",
- "trackingId": "string"
}, - "resolvent": {
- "type": "denied",
- "resolved": true,
- "date": "2019-08-24T14:15:22Z"
}, - "processingOutcome": {
- "approved": true,
- "declineReasonCode": "string"
}, - "fees": {
- "taxType": "string",
- "taxAmount": 0,
- "taxAmountFx": 0,
- "taxNarrative": "string"
}, - "externalToken": "string",
- "transType": {
- "codeOraSys": "string",
- "description": "string",
- "action": "DR",
- "directionType": "D",
- "ryvylLabel": "string",
- "ryvylStatement": "string",
- "mcc": "string",
- "settlementCode": "string"
}, - "transStatus": "pending",
- "createdAt": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "total": 0,
- "page": 0,
- "limit": 0,
- "totalPages": 0
}
}Returns the live availableBalance for every IBAN the calling
partner owns. The same IBAN can appear via two onboardings (e.g.
a cardholder who is also a tenant admin) — results are
deduplicated by accountNumber so each IBAN appears exactly once.
Per-IBAN failures are surfaced in the response with
status: "error" and an errorMessage field — never silently
zeroed. The overall HTTP status remains 200 so a partner UI
can still render the IBANs that succeeded.
The optional ?iban=… query parameter narrows the result set
to a single IBAN.
| iban | string Optional IBAN filter. |
| success | boolean |
| count | integer |
Array of objects (BalanceEntry) |
{- "success": true,
- "count": 0,
- "data": [
- {
- "iban": "string",
- "availableBalance": 0,
- "currency": "string",
- "accountHolder": "string",
- "isB2bShared": true,
- "accountStatus": "string",
- "status": "ok",
- "errorMessage": "string"
}
]
}Live availableBalance for a single IBAN the partner owns.
Same failure semantics as /balances: status: "error" on a
per-IBAN failure.
| iban required | string IBAN whose balance to fetch. Must belong to the calling partner; foreign IBANs return 404 without enumeration. |
| success | boolean |
| count | integer |
Array of objects (BalanceEntry) |
{- "success": true,
- "count": 0,
- "data": [
- {
- "iban": "string",
- "availableBalance": 0,
- "currency": "string",
- "accountHolder": "string",
- "isB2bShared": true,
- "accountStatus": "string",
- "status": "ok",
- "errorMessage": "string"
}
]
}Card-level endpoints that operate on a single card. The :id
path parameter is the cardKey (for example
KDRYV0XXXXXXXXXX). Every endpoint under /cards/:id/... is
scoped to the calling partner.
Returns every card owned by the authenticated partner across all
account types (B2B + individual). Not tenant-scoped per-card —
this is a full partner-wide list in a single response. There is no
pagination on this endpoint; the payload includes a count value
and the complete data array.
| status | string (CardStatus)
Filter by card status. | ||||||||||||||||||
| type | string Enum: "virtual" "physical"
| ||||||||||||||||||
| search | string Case-insensitive search on |
| count | integer Number of cards in |
Array of objects (PartnerCardListItem) Cards sorted by |
{- "count": 0,
- "data": [
- {
- "_id": "string",
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "cardType": "VIRTUAL",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string",
- "nickName": "string",
- "set_pin": true,
- "set_password": true,
- "authPhoneNumber": "string",
- "deliveryMethod": { },
- "deliveryAddress": {
- "street": "string",
- "buildingNumber": "string",
- "apartmentNumber": "string",
- "stateProvince": "string",
- "city": "string",
- "zipCode": "string",
- "country": "string"
}, - "cardMask": "string",
- "onboarding": "string",
- "b2bClient": "string",
- "isAdminBlocked": true,
- "limitOverrides": {
- "property1": {
- "defaultValue": 0,
- "maxValue": 0
}, - "property2": {
- "defaultValue": 0,
- "maxValue": 0
}
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "__v": 0
}
]
}Returns the prepaid card requests of every cardholder of the partner: its own individuals and the
cardholders of its business accounts. No cardholder id is needed. Newest first, one page at a time
(page and limit, up to 100 per page). Each item has a cardholderId, a status and an
isFinished flag. pagination tells whether there are more pages. A page or limit that is not
a positive whole number is a 400.
| page | integer >= 1 Default: 1 Example: page=1 Page number for pagination. Starts at |
| limit | integer [ 1 .. 100 ] Default: 100 Example: limit=20 Number of prepaid card requests per page. At most |
| sortBy | string Default: "createdAt" Value: "createdAt" Field to sort by. Only |
| sortOrder | string Default: "desc" Enum: "desc" "asc"
|
| count | integer Number of requests on this page. |
Array of objects (PrepaidCardRequestStatus) | |
object (Pagination) |
{- "count": 0,
- "data": [
- {
- "prepaidRequestId": "6840a1f2c3d4e5f6a7b8c9d0",
- "cardKind": "physical",
- "cardholderId": "6836df4c98653594cae54d72",
- "productCode": "R007",
- "currency": "EUR",
- "status": "PENDING",
- "isFinished": false,
- "statusMessage": "The card is being created. This usually takes 2-3 minutes.",
- "cardKey": null,
- "feesReleased": false,
- "createdAt": "2026-10-08T10:15:00.000Z",
- "statusUpdatedAt": "2026-10-08T10:17:10.000Z"
}
], - "pagination": {
- "page": 0,
- "limit": 0,
- "total": 0,
- "pages": 0,
- "hasNextPage": true,
- "hasPrevPage": true
}
}Returns the money on each prepaid card asked for. Up to 50 card keys per request, comma separated. One answer per key, in the order asked.
A card that does not exist, is not a prepaid card, or does not belong to your partner is answered with
found: false - the same answer in each case. availableBalance: null means the balance could not be
read right now; it is not zero.
| cardKeys required | string Example: cardKeys=1000234567,1000234568 Comma separated card keys ( |
Array of objects (PrepaidCardBalance) | |||||||||||
Array
| |||||||||||
{- "data": [
- {
- "cardKey": "string",
- "found": true,
- "currency": "EUR",
- "availableBalance": 25.5,
- "message": "Card not found"
}
]
}Returns full card details. Does not include the PAN or CVV — use the dedicated sensitive endpoints below for those.
| id required | string Card |
object (PartnerCardDetails) Full card details returned by Card-only — does not include | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
{- "data": {
- "cardHash": "string",
- "cardKey": "string",
- "cardUuid": "string",
- "cardMask": "string",
- "expDate": "string",
- "issueDate": "2019-08-24",
- "status": "ACTIVE",
- "statusCode": "string",
- "terminating": true,
- "productCode": "string",
- "productDesc": "string",
- "holder": "string",
- "accounts": [
- {
- "accNo": "string",
- "primary": true,
- "currencyCode": "string",
- "currencyName": "string"
}
], - "embossName1": "string",
- "embossName2": "string",
- "source": "string",
- "kind": "DEBIT",
- "main": true,
- "limits": [
- {
- "name": "POS_PUR_LMT",
- "value": 0,
- "noLimit": true
}
], - "visual": "string",
- "visualDesc": "string",
- "tokenized": true,
- "delivery": {
- "deliveryType": "string",
- "deliveryBranch": "string",
- "oneTimeDeliveryBranch": "string"
}, - "contactless": true,
- "cardTechnologyMode": "string",
- "creationDate": "2019-08-24",
- "creationUser": "string",
- "oldPlastic": "string",
- "autoRenewal": true,
- "saleChannelCode": "string"
}
}Returns the current card status + status code. Only status and
statusCode are returned (no cardKey, since the cardKey is
already in the URL path).
| id required | string Card |
object (CardStatusOnlyResponse) Body returned by No | |||||||||||||||||||||||
| |||||||||||||||||||||||
{- "data": {
- "status": "ACTIVE",
- "statusCode": "string"
}
}Locks the card. The card stays in the holder's possession but cannot authorize transactions. The request body is optional; send an empty JSON object or omit it.
| id required | string Card |
| expDate required | string^(0[1-9]|1[0-2])\/\d{4}$ Card expiration in |
| reason | string Audit reason (free-form) |
object (CardActionResponse) Response returned by every card-lifecycle endpoint that does not
move the card to a new No Required: | |||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||
{ }{- "data": {
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string"
}
}Unlocks a previously-locked card. The request body is optional.
| id required | string Card |
| expDate required | string^(0[1-9]|1[0-2])\/\d{4}$ Card expiration in |
| reason | string Audit reason (free-form) |
object (CardActionResponse) Response returned by every card-lifecycle endpoint that does not
move the card to a new No Required: | |||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||
{ }{- "data": {
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string"
}
}Activates a freshly-issued card. The request body is optional.
| id required | string Card |
| expDate required | string^(0[1-9]|1[0-2])\/\d{4}$ Card expiration in |
| reason | string Audit reason (free-form) |
object (CardActionResponse) Response returned by every card-lifecycle endpoint that does not
move the card to a new No Required: | |||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||
{ }{- "data": {
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string"
}
}Temporarily locks the card (e.g. while the holder travels). Optional body.
| id required | string Card |
| expDate required | string^(0[1-9]|1[0-2])\/\d{4}$ Card expiration in |
| reason | string Audit reason (free-form) |
object (CardActionResponse) Response returned by every card-lifecycle endpoint that does not
move the card to a new No Required: | |||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||
{ }{- "data": {
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string"
}
}Generic card restriction. Body is optional.
| id required | string Card |
| expDate | string^(0[1-9]|1[0-2])\/\d{4}$ |
| reason | string |
| description | string |
| cardLocation | string Where the card was last seen |
object (CardActionResponse) Response returned by every card-lifecycle endpoint that does not
move the card to a new No Required: | |||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||
{- "expDate": "12/2030",
- "reason": "custom",
- "description": "Optional description"
}{- "data": {
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string"
}
}Restricts the card as lost. The card cannot be used; the holder must request a replacement. Body is optional.
| id required | string Card |
| expDate | string^(0[1-9]|1[0-2])\/\d{4}$ |
| reason | string |
| description | string |
| cardLocation | string Where the card was last seen |
object (CardActionResponse) Response returned by every card-lifecycle endpoint that does not
move the card to a new No Required: | |||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||
{ }{- "data": {
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string"
}
}Restricts the card as stolen. Body is optional.
| id required | string Card |
| expDate | string^(0[1-9]|1[0-2])\/\d{4}$ |
| reason | string |
| description | string |
| cardLocation | string Where the card was last seen |
object (CardActionResponse) Response returned by every card-lifecycle endpoint that does not
move the card to a new No Required: | |||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||
{ }{- "data": {
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string"
}
}Restricts the card as closed. Body is optional.
| id required | string Card |
| expDate | string^(0[1-9]|1[0-2])\/\d{4}$ |
| reason | string |
| description | string |
| cardLocation | string Where the card was last seen |
object (CardActionResponse) Response returned by every card-lifecycle endpoint that does not
move the card to a new No Required: | |||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||
{ }{- "data": {
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string"
}
}Restricts the card as fraud. Body is optional.
| id required | string Card |
| expDate | string^(0[1-9]|1[0-2])\/\d{4}$ |
| reason | string |
| description | string |
| cardLocation | string Where the card was last seen |
object (CardActionResponse) Response returned by every card-lifecycle endpoint that does not
move the card to a new No Required: | |||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||
{ }{- "data": {
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string"
}
}Updates the embossed name on the card. Note: spaces are not allowed in the emboss-name request.
| id required | string Card |
| embossName1 required | string <= 22 characters |
| embossName2 | string <= 19 characters |
object (CardActionResponse) Response returned by every card-lifecycle endpoint that does not
move the card to a new No Required: | |||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||
{- "embossName1": "CASEY SAMPLE"
}{- "data": {
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string"
}
}Replaces the physical card. The returned response carries a
new cardKey — store the new value because the old key is
no longer valid for any subsequent operation on this card.
The response includes cardMask. If the upstream card-issuing
platform is temporarily unavailable, cardMask may be null.
| id required | string Card |
| expDate required | string^(0[1-9]|1[0-2])\/\d{4}$ |
| reason | string |
| pinMailer | string Postal pin-mailer reference |
object (ReplaceCardResponse) Body returned by Carries every field of | |||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||
{- "expDate": "06/2029"
}{- "data": {
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string",
- "cardMask": "string"
}
}Re-issues the card (e.g. PIN reissue, expiration). The returned
response carries a new cardKey — store the new value
because the old key is no longer valid for any subsequent
operation on this card. The old card is closed.
The response includes cardMask. If the upstream card-issuing
platform is temporarily unavailable, cardMask may be null.
| id required | string Card |
| expDate required | string^(0[1-9]|1[0-2])\/\d{4}$ |
| reason | string |
| pinMailer | string Postal pin-mailer reference |
object (ReplaceCardResponse) Body returned by Carries every field of | |||||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||||
{- "reason": "Test resign"
}{- "data": {
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string",
- "cardMask": "string"
}
}Returns the CVV2 for the card. Sensitive — never log this response. The successful response contains an encrypted envelope for the partner's registered encryption public key. The partner decrypts it with its private key. No plaintext CVV is returned.
| id required | string Card |
| expDate required | string^(0[1-9]|1[0-2])\/\d{4}$ Card expiration in |
required | object (EncryptedCardData) Minimal encrypted envelope for a single sensitive card value. Cipher: ECDH-ES on curve secp521r1 (P-521), HKDF-SHA256, AES-256-GCM. | ||||||||||||||||
| |||||||||||||||||
{- "data": {
- "v": 1,
- "p": "cvv2",
- "c": "string",
- "k": "string",
- "e": "string",
- "iv": "string",
- "ct": "string",
- "t": "string"
}
}Returns the full PAN for the card. Highly sensitive — never log this response. The successful response contains an encrypted envelope for the partner's registered encryption public key. The partner decrypts it with its private key. No plaintext PAN is returned.
| id required | string Card |
| expDate required | string^(0[1-9]|1[0-2])\/\d{4}$ Card expiration in |
required | object (EncryptedCardData) Minimal encrypted envelope for a single sensitive card value. Cipher: ECDH-ES on curve secp521r1 (P-521), HKDF-SHA256, AES-256-GCM. | ||||||||||||||||
| |||||||||||||||||
{- "data": {
- "v": 1,
- "p": "cvv2",
- "c": "string",
- "k": "string",
- "e": "string",
- "iv": "string",
- "ct": "string",
- "t": "string"
}
}Updates the 3-D Secure answer configured on the card.
| id required | string Card |
| Idempotency-Key | string <uuid> Example: 550e8400-e29b-41d4-a716-446655440000 Optional idempotency key to ensure safe retries for non-GET requests. When provided, the API remembers your request and returns the exact same result if the same key is sent within 60 seconds. This protects against duplicate operations in case of network timeouts or accidental retries. Recommended: Use a UUID v4 for each logical operation. Response headers:
|
| answer required | string <= 200 characters |
| message | string Human-readable success message. |
{- "answer": "my-secure-answer"
}{- "message": "Success"
}Updates the phone number used to deliver the 3-D Secure OTP.
Which phone number is used for 3-D Secure? The cardholder record carries two phone fields:
authPhoneNumber — the dedicated phone for 3-D Secure OTP deliveryphoneNumber — the general contact phoneAt 3-D Secure time we use authPhoneNumber if it is set; if it is
empty, we fall back to phoneNumber. The value you POST in
newPhoneNumber on this endpoint becomes the new authPhoneNumber.
Response shape. The success path returns exactly
{ "success": true }. The warnings field is only present
when a downstream sync silently failed — it is omitted entirely
on the all-clean path, never returned as an empty array.
| id required | string Card |
| newPhoneNumber required | string <= 16 characters ^\+?\d{4,16}$ New 3-D Secure phone number. Stored as the cardholder's
|
| success | boolean |
| warnings | Array of strings Present only when at least one downstream sync failed. Each entry is a human-readable description of one failed downstream store. Omitted entirely on the success path. |
{- "newPhoneNumber": "+10000000000"
}{- "success": true,
- "warnings": [
- "string"
]
}Resets the cardholder's PIN-attempt counter.
The response carries the same CardActionResponse shape as the
other card-lifecycle endpoints (lock, unlock, activate, restrict,
etc.) — a flat card-action row, not the full card details.
| id required | string Card |
object (CardActionResponse) Response returned by every card-lifecycle endpoint that does not
move the card to a new No Required: | |||||||||||||||||||||||||||||||||||||||||||||
| |||||||||||||||||||||||||||||||||||||||||||||
{- "data": {
- "cardHash": "string",
- "cardKey": "string",
- "expDate": "string",
- "status": "ACTIVE",
- "statusCode": "string",
- "kind": "DEBIT",
- "productCode": "string",
- "productDesc": "string",
- "main": true,
- "holder": "string",
- "accNo": "string",
- "embossName1": "string",
- "embossName2": "string"
}
}Changes the card PIN. newPin is the raw 4–6 digit PIN; it is
encrypted before being sent to the card-issuing platform.
| id required | string Card |
| newPin required | string [ 4 .. 6 ] characters ^\d{4,6}$ New PIN, raw 4–6 digits. |
| cardHash | string 128-char hex card hash. | ||||||||||||||||||
| cardKey | string 16-char card key. The user-facing identifier used as | ||||||||||||||||||
| cardUuid | string or null Card-issuing platform internal UUID. | ||||||||||||||||||
| cardMask | string Masked card number (e.g. | ||||||||||||||||||
| expDate | string Card expiry as | ||||||||||||||||||
| issueDate | string <date> Card issue date as | ||||||||||||||||||
| status | string (CardStatus)
Card lifecycle state as returned by IT Card. | ||||||||||||||||||
| statusCode | string Raw card status code from the card-issuing platform (e.g.
| ||||||||||||||||||
| terminating | boolean
| ||||||||||||||||||
| productCode | string 4-char product code (e.g. | ||||||||||||||||||
| productDesc | string or null Human-readable product name (e.g. | ||||||||||||||||||
| holder | string Card holder client code (e.g. | ||||||||||||||||||
Array of objects (PartnerCardAccount) One or more accounts the card is linked to. | |||||||||||||||||||
| embossName1 | string or null Embossed cardholder name (line 1, max 22 chars). | ||||||||||||||||||
| embossName2 | string or null Embossed company name (line 2, max 19 chars). | ||||||||||||||||||
| source | string Card source. Common values: | ||||||||||||||||||
| kind | string Enum: "DEBIT" "CREDIT" "PREPAID" Card kind. | ||||||||||||||||||
| main | boolean
| ||||||||||||||||||
Array of objects (PartnerCardLimit) Per-card limit rows. | |||||||||||||||||||
| visual | string Visual code (usually equal to | ||||||||||||||||||
| visualDesc | string or null Human-readable visual description. | ||||||||||||||||||
| tokenized | boolean
| ||||||||||||||||||
object (PartnerCardDelivery) Card delivery metadata. Only | |||||||||||||||||||
| contactless | boolean
| ||||||||||||||||||
| cardTechnologyMode | string Card technology mode. Common values: | ||||||||||||||||||
| creationDate | string <date> Card creation date as | ||||||||||||||||||
| creationUser | string or null Username/operator that created the card. | ||||||||||||||||||
| oldPlastic | string or null Previous card plastic reference. Only set after a replace/resign. | ||||||||||||||||||
| autoRenewal | boolean
| ||||||||||||||||||
| saleChannelCode | string or null 3-char sale channel code. |
{- "newPin": "000000"
}{- "cardHash": "string",
- "cardKey": "string",
- "cardUuid": "string",
- "cardMask": "string",
- "expDate": "string",
- "issueDate": "2019-08-24",
- "status": "ACTIVE",
- "statusCode": "string",
- "terminating": true,
- "productCode": "string",
- "productDesc": "string",
- "holder": "string",
- "accounts": [
- {
- "accNo": "string",
- "primary": true,
- "currencyCode": "string",
- "currencyName": "string"
}
], - "embossName1": "string",
- "embossName2": "string",
- "source": "string",
- "kind": "DEBIT",
- "main": true,
- "limits": [
- {
- "name": "POS_PUR_LMT",
- "value": 0,
- "noLimit": true
}
], - "visual": "string",
- "visualDesc": "string",
- "tokenized": true,
- "delivery": {
- "deliveryType": "string",
- "deliveryBranch": "string",
- "oneTimeDeliveryBranch": "string"
}, - "contactless": true,
- "cardTechnologyMode": "string",
- "creationDate": "2019-08-24",
- "creationUser": "string",
- "oldPlastic": "string",
- "autoRenewal": true,
- "saleChannelCode": "string"
}Returns every spending limit for the card.
Use these fields to decide what you can set later with PATCH:
value — current limit on the cardapprovalThreshold — values at or below this apply immediately
(no approval)max — highest value you may request (when present). Values above
max are rejected with 400pendingValue — included only when an in-flight change differs
from valueIf a limit has no finite cap, max / approvalThreshold may be omitted.
| id required | string Card |
Array of objects (CardLimit) | |
| cardType | string Enum: "VIRTUAL" "PHYSICAL" |
| limitChangeFee | number <double> Fee that may apply when a limit change requires approval. |
{- "limits": [
- {
- "name": "POS_PUR_LMT",
- "value": 0.1,
- "desc": "string",
- "type": "AMOUNT",
- "life": "DAY",
- "balanceType": "CASH",
- "noLimit": true,
- "min": 0.1,
- "max": 0.1,
- "default": 0.1,
- "pendingValue": 0.1,
- "approvalThreshold": 0.1
}
], - "cardType": "VIRTUAL",
- "limitChangeFee": 0.1
}Updates one or more card limits in a single call. Each item needs a
concrete name (a CardLimitType) and a non-negative value.
First call GET /cards/{id}/limits and use approvalThreshold and
max from that response.
For each requested value:
max → rejected with 400.approvalThreshold, but at or below max → the whole
batch needs approval. Nothing changes on the card yet.
Response is 201 with pendingApproval: true and a taskId.
A new batch cancels any older pending request for the same card.approvalThreshold → applied immediately
(200).| id required | string Card |
| Idempotency-Key | string <uuid> Example: 550e8400-e29b-41d4-a716-446655440000 Optional idempotency key to ensure safe retries for non-GET requests. When provided, the API remembers your request and returns the exact same result if the same key is sent within 60 seconds. This protects against duplicate operations in case of network timeouts or accidental retries. Recommended: Use a UUID v4 for each logical operation. Response headers:
|
| name required | string (CardLimitType) Enum: "POS_PUR_LMT" "ATM_CCA_LMT" "CNP_AMT_LMT" "MONTH_POS_PUR_LMT" "MONTH_ATM_CCA_LMT" "MONTH_AMT_CNP_LMT" "ATM_USE_LMT" "POS_USE_LMT" "MONTH_TRANS_AMT_LMT" "PERIOD_TRANS_AMT" "ECOMM_AMT_LMT" Which limit types are configurable depends on the card's product — not every product configures every type. For a full list of limit types, see Limit types. |
| value required | number <double> >= 0 |
| success | boolean |
| pendingApproval | boolean |
Array of objects (CardLimit) |
| pendingApproval | boolean |
| taskId | string |
[- {
- "name": "POS_PUR_LMT",
- "value": 1000
}
]{- "success": true,
- "pendingApproval": false,
- "data": [
- {
- "name": "POS_PUR_LMT",
- "value": 0.1,
- "desc": "string",
- "type": "AMOUNT",
- "life": "DAY",
- "balanceType": "CASH",
- "noLimit": true,
- "min": 0.1,
- "max": 0.1,
- "default": 0.1,
- "pendingValue": 0.1,
- "approvalThreshold": 0.1
}
]
}Returns how much is still left for one limit before it is hit.
Example: for POS_PUR_LMT, how much of today's purchase limit is
still unused.
Response fields:
name — limit typevalue — current configured limitavailable — remaining amount or count| id required | string Card |
| limitName required | string (CardLimitType) Enum: "POS_PUR_LMT" "ATM_CCA_LMT" "CNP_AMT_LMT" "MONTH_POS_PUR_LMT" "MONTH_ATM_CCA_LMT" "MONTH_AMT_CNP_LMT" "ATM_USE_LMT" "POS_USE_LMT" "MONTH_TRANS_AMT_LMT" "PERIOD_TRANS_AMT" "ECOMM_AMT_LMT" A |
| name | string (CardLimitType) Enum: "POS_PUR_LMT" "ATM_CCA_LMT" "CNP_AMT_LMT" "MONTH_POS_PUR_LMT" "MONTH_ATM_CCA_LMT" "MONTH_AMT_CNP_LMT" "ATM_USE_LMT" "POS_USE_LMT" "MONTH_TRANS_AMT_LMT" "PERIOD_TRANS_AMT" "ECOMM_AMT_LMT" Which limit types are configurable depends on the card's product — not every product configures every type. For a full list of limit types, see Limit types. |
| value | number <double> |
| available | number <double> Remaining amount (or count) before this limit is hit. |
{- "name": "POS_PUR_LMT",
- "value": 0.1,
- "available": 0.1
}Returns the card with its balance, its owner, and the main accounts the card can be loaded from, with
their balances. Use one of sourceAccounts[].id as sourceAccountId to load the card.
The money always comes from the card's owner: the individual for a card of an individual, the company for a card of a B2B cardholder.
| id required | string Card |
object | |||||||||||||
| |||||||||||||
{- "data": {
- "card": {
- "cardKey": "string",
- "nickname": "string",
- "last4": "string",
- "productCode": "R008",
- "currency": "EUR",
- "availableBalance": 0
}, - "owner": {
- "type": "individual",
- "name": "string"
}, - "sourceAccounts": [
- {
- "id": "string",
- "iban": "string",
- "label": "string",
- "currency": "EUR",
- "isPrimary": true,
- "availableBalance": 0
}
], - "currency": "EUR",
- "minAmount": 0.01,
- "hasOpenLoad": true
}
}The loads of the card, newest first.
| id required | string Card |
| page | integer >= 1 Default: 1 |
| limit | integer [ 1 .. 50 ] Default: 10 |
Array of objects (PrepaidCardLoad) | |
object |
{- "data": [
- {
- "id": "string",
- "cardKey": "string",
- "amount": 25,
- "currency": "EUR",
- "status": "PENDING",
- "message": "string",
- "sourceIban": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "totalDocs": 0,
- "limit": 0,
- "totalPages": 0,
- "page": 0,
- "pagingCounter": 0,
- "hasPrevPage": true,
- "hasNextPage": true,
- "prevPage": 0,
- "nextPage": 0
}
}Moves money from one of the owner's main accounts to the prepaid card.
The answer is 201 with the load. Its status is usually SUBMITTED: the bank accepted the payment
and books it within a few seconds. Ask for the load with
GET /cards/{id}/prepaid/loads/{loadId} until status is SUCCESS or FAILED.
UNCONFIRMED means the bank did not answer: the money may or may not have moved. PayNovus checks it.
Do not load the card again until the load is finished - a new load of the card is refused (409) while
one is not finished.
idempotencyKey is required: generate a new one for each load. A request with a key you already used is
refused with 409 and code LOAD_ALREADY_EXISTS, and nothing is paid again. When that load is of the same
card, its loadId is in the answer. Keys are yours alone: a key used by someone else does not conflict.
| id required | string Card |
| sourceAccountId required | string One of |
required | string or number At most two decimals, dot separator. Between 0.01 and 1000000. |
| idempotencyKey required | string A new key for each load, e.g. a UUID. Checked against your own loads only. |
object (PrepaidCardLoad) | |||||||||||||||||||||
| |||||||||||||||||||||
{- "sourceAccountId": "6836df4c98653594cae54d80",
- "amount": "25.00",
- "idempotencyKey": "3f6c2a1e-9b7d-4c1a-8e2f-5d4b3a2c1e0f"
}{- "data": {
- "id": "string",
- "cardKey": "string",
- "amount": 25,
- "currency": "EUR",
- "status": "PENDING",
- "message": "string",
- "sourceIban": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z"
}
}Returns one load of the card. A SUBMITTED load is checked with the bank when you ask, so ask every few
seconds until status is SUCCESS or FAILED. A load of another card is a 404.
| id required | string Card |
| loadId required | string The |
object (PrepaidCardLoad) | |||||||||||||||||||||
| |||||||||||||||||||||
{- "data": {
- "id": "string",
- "cardKey": "string",
- "amount": 25,
- "currency": "EUR",
- "status": "PENDING",
- "message": "string",
- "sourceIban": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "completedAt": "2019-08-24T14:15:22Z"
}
}Returns the maximum number of physical cards a single account
may hold at any time. The cap is platform-wide, not per-card, so
the endpoint is not scoped to a :id.
Use this to decide whether a new physical card can be issued for an account.
object | |||
| |||
{- "data": {
- "limit": "10"
}
}Returns the maximum number of virtual cards a single account
may hold at any time. The cap is platform-wide, not per-card, so
the endpoint is not scoped to a :id.
Use this to decide whether a new virtual card can be issued for an account.
object | |||
| |||
{- "data": {
- "limit": "10"
}
}Pre-issuance check for the rolling virtual-card issuance cap.
Lets a partner surface a "you're approaching your virtual card limit"
warning in their own UI before opening the issuance flow, instead of
discovering the cap only when the issuance call fails with 429.
Read-only. A skipped or stale check can never let an extra card through — the authoritative block lives in the issuance path, and both the pre-check and the issuance call evaluate the same quota.
When no cardholderId is supplied (neither path segment nor query
string), the partner's first direct individual onboarding is
used. A partner with no direct individuals gets 404 and must
call the {cardholderId} variant for B2B cardholders.
Scope: applies to non-B2B cardholders only (partner-owned
individuals). For B2B cardholders the response returns
applies: false with a neutral non-blocking quota — issuance for
B2B cardholders is governed by the per-account concurrent cap
(GET /cards/hold-limits/virtual), not the rolling cap.
B2B cardholder behavior: if the quota does not apply to the
resolved cardholder, the response is always applies: false,
status: 'OK', used: 0, with remaining = limit and
nextSlotFreesAt: null. The quota object is still returned (never
omitted) so the partner client never has to branch on scope — any
code that reads data.status === 'LIMIT_EXCEEDED' simply never
fires for B2B cardholders.
| cardholderId | string Optional cardholder identifier. When supplied, must belong to the calling partner — either directly (a partner-owned individual) or hosted under one of the partner's B2B tenants. Equivalent to the |
| success | boolean |
object (VirtualCardWindowQuota) Rolling-window virtual-card issuance decision for one cardholder.
See When |
{- "success": true,
- "data": {
- "applies": true,
- "status": "OK",
- "used": 0,
- "limit": 0,
- "remaining": 0,
- "windowDays": 1,
- "nextSlotFreesAt": "2019-08-24T14:15:22Z"
}
}Pre-issuance check for the rolling virtual-card issuance cap on a specific cardholder.
The cardholder must be accessible to the calling partner:
Ownership-mismatch returns 404 Not Found with no further detail — identical whether the cardholder does not exist or belongs to another partner (no enumeration).
Read-only. A skipped or stale check can never let an extra card through — the authoritative block lives in the issuance path, and both the pre-check and the issuance call evaluate the same quota.
Scope: applies to non-B2B cardholders only (partner-owned
individuals and direct individuals). For B2B cardholders the
response returns applies: false with a neutral non-blocking
quota — issuance for B2B cardholders is governed by the
per-account concurrent cap (GET /cards/hold-limits/virtual),
not the rolling cap.
B2B cardholder behavior: if the quota does not apply to the
resolved cardholder, the response is always applies: false,
status: 'OK', used: 0, with remaining = limit and
nextSlotFreesAt: null. The quota object is still returned (never
omitted) so the partner client never has to branch on scope — any
code that reads data.status === 'LIMIT_EXCEEDED' simply never
fires for B2B cardholders, and any code that reads data.used
sees 0 instead of a misleading real count.
Status field guide:
status |
Meaning |
|---|---|
OK |
Under the warning band — proceed silently. |
WARNING_THRESHOLD_REACHED |
Still allowed, but the cardholder is close to the cap. Tell them. |
LIMIT_EXCEEDED |
Cap reached; issuance will be blocked with 429. |
| cardholderId required | string Cardholder identifier. Must belong to the calling partner — either directly (a partner-owned individual) or hosted under one of the partner's B2B tenants. Equivalent to |
| success | boolean |
object (VirtualCardWindowQuota) Rolling-window virtual-card issuance decision for one cardholder.
See When |
{- "success": true,
- "data": {
- "applies": true,
- "status": "OK",
- "used": 0,
- "limit": 0,
- "remaining": 0,
- "windowDays": 1,
- "nextSlotFreesAt": "2019-08-24T14:15:22Z"
}
}Fee and delivery-method lookups. The issuing/delivery fee endpoints validate the request payload before returning a quote.
Returns PocztaPost + DHL delivery methods available for the given
country. The match is case-insensitive on the full country
name stored in the Country column of the source Excel upload
(e.g. Bulgaria, BULGARIA, bulgaria all match the same row).
Both collections are queried and their results merged in one
response — there is no pagination.
The response is wrapped under data. The payload is dynamic:
each records[] entry carries whatever columns the original
Excel template held (delivery times, weight tiers, zone names,
prices, etc.), in addition to upload-metadata fields prefixed
with _.
| country required | string Example: country=Bulgaria Full country name to look up (case-insensitive). Matched
against the |
object (DeliveryMethodsResponse) Response body returned by | |||||||||||
| |||||||||||
{- "data": {
- "success": true,
- "country": "string",
- "polishPost": {
- "records": [
- {
- "_id": "string",
- "Country": "string",
- "_fileName": "string",
- "_sheetName": "string",
- "_rowIndex": 0,
- "_totalRows": 0,
- "_uploadedAt": "2019-08-24T14:15:22Z",
- "_createdAt": "2019-08-24T14:15:22Z",
- "_updatedAt": "2019-08-24T14:15:22Z"
}
], - "count": 0
}, - "dhl": {
- "records": [
- {
- "_id": "string",
- "Country": "string",
- "_fileName": "string",
- "_sheetName": "string",
- "_rowIndex": 0,
- "_totalRows": 0,
- "_uploadedAt": "2019-08-24T14:15:22Z",
- "_createdAt": "2019-08-24T14:15:22Z",
- "_updatedAt": "2019-08-24T14:15:22Z"
}
], - "count": 0
}, - "totalCount": 0
}
}Returns the fee for issuing a card. The endpoint looks up the
fee by CustomerType + ProductType (and optionally
cardKey / clientId / iban for narrowing).
| CustomerType required | string Enum: "Consumer Debit" "Business Debit" "Consumer Prepaid" "Business Prepaid" |
| ProductType required | string Enum: "R001" "R002" "R003" "R004" "R005" "R006" |
| cardKey | string Optional — card |
| clientId | string Optional — cardholder |
| iban | string Optional — account IBAN to narrow the fee lookup. |
| _id | string Fee record |
| deletedAt | string or null <date-time> Soft-delete timestamp, |
| GLAccountName | string GL account name in the accounting system (e.g. |
| feeCode | string Fee code (e.g. |
| operationType | string Operation type this fee applies to (e.g. |
| customerType | string Customer type this fee applies to (e.g. |
| productType | string Product type this fee applies to (e.g. |
| trigger | string What triggers the fee (e.g. |
| loopOnCard | boolean Whether the fee applies once per card or per transaction. |
| displayDescriptor | string Human-readable descriptor shown in statements and admin UIs. |
| type | string Fee class (e.g. |
| currency | string ISO 4217 currency code (e.g. |
| fixedFee | number <double> Flat fee amount in |
| percentageFee | number <double> Percentage-based fee component, when applicable. |
| fxFixedFee | number <double> Flat fee applied to FX transactions. |
| fxPercentageFee | number <double> Percentage-based fee applied to FX transactions. |
object (FeeSpecialCondition) Special-condition block present on delivery-fee responses (and some issuing-fee responses). All keys are optional and reflect provider-specific overrides. | |
| createdAt | string <date-time> |
| updatedAt | string <date-time> |
| __v | integer Internal document version key. |
| property name* additional property | any |
{- "CustomerType": "Consumer Debit",
- "ProductType": "R001"
}{- "_id": "string",
- "deletedAt": "2019-08-24T14:15:22Z",
- "GLAccountName": "string",
- "feeCode": "string",
- "operationType": "string",
- "customerType": "string",
- "productType": "string",
- "trigger": "string",
- "loopOnCard": true,
- "displayDescriptor": "string",
- "type": "string",
- "currency": "string",
- "fixedFee": 0.1,
- "percentageFee": 0.1,
- "fxFixedFee": 0.1,
- "fxPercentageFee": 0.1,
- "specialCondition": {
- "noEEAfee": 0.1
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "__v": 0
}Returns the fee for delivering a card. The endpoint looks up the
fee by CustomerType + ProductType (and optionally
cardKey / clientId / iban for narrowing).
| CustomerType required | string Enum: "Consumer Debit" "Business Debit" "Consumer Prepaid" "Business Prepaid" |
| ProductType required | string Enum: "R001" "R002" "R003" "R004" "R005" "R006" |
| cardKey | string Optional — card |
| clientId | string Optional — cardholder |
| iban | string Optional — account IBAN to narrow the fee lookup. |
| _id | string Fee record |
| deletedAt | string or null <date-time> Soft-delete timestamp, |
| GLAccountName | string GL account name in the accounting system (e.g. |
| feeCode | string Fee code (e.g. |
| operationType | string Operation type this fee applies to (e.g. |
| customerType | string Customer type this fee applies to (e.g. |
| productType | string Product type this fee applies to (e.g. |
| trigger | string What triggers the fee (e.g. |
| loopOnCard | boolean Whether the fee applies once per card or per transaction. |
| displayDescriptor | string Human-readable descriptor shown in statements and admin UIs. |
| type | string Fee class (e.g. |
| currency | string ISO 4217 currency code (e.g. |
| fixedFee | number <double> Flat fee amount in |
| percentageFee | number <double> Percentage-based fee component, when applicable. |
| fxFixedFee | number <double> Flat fee applied to FX transactions. |
| fxPercentageFee | number <double> Percentage-based fee applied to FX transactions. |
object (FeeSpecialCondition) Special-condition block present on delivery-fee responses (and some issuing-fee responses). All keys are optional and reflect provider-specific overrides. | |
| createdAt | string <date-time> |
| updatedAt | string <date-time> |
| __v | integer Internal document version key. |
| property name* additional property | any |
{- "CustomerType": "Consumer Debit",
- "ProductType": "R001"
}{- "_id": "string",
- "deletedAt": "2019-08-24T14:15:22Z",
- "GLAccountName": "string",
- "feeCode": "string",
- "operationType": "string",
- "customerType": "string",
- "productType": "string",
- "trigger": "string",
- "loopOnCard": true,
- "displayDescriptor": "string",
- "type": "string",
- "currency": "string",
- "fixedFee": 0.1,
- "percentageFee": 0.1,
- "fxFixedFee": 0.1,
- "fxPercentageFee": 0.1,
- "specialCondition": {
- "noEEAfee": 0.1
}, - "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z",
- "__v": 0
}Everything a partner needs to receive and verify our outbound webhooks.
A partner-facing webhook is a POST we make to the url the
partner configured, when a business process reaches its final
outcome — an administrator approving or rejecting a B2B account,
an individual, or a cardholder, or an IBAN settings / IBAN link
change being applied. The partner configures a single endpoint
and a signing secret; every event type goes to that one url, and
what happened travels in the body's type.
The endpoints under this tag are the partner-facing management surface:
| Endpoint | What it does |
|---|---|
GET /api/partner/webhooks/public-key |
Fetch the public key partners verify signatures with. |
PUT /api/partner/webhooks/secret |
Set or rotate the partner's own signing secret. |
GET /api/partner/webhooks/events |
List every supported event and whether it is on. |
PATCH /api/partner/webhooks/events |
Switch one or more events on or off. |
GET /api/partner/logs/webhooks |
Read the partner's own delivery history, one row per attempt. |
Every endpoint is scoped to the partner id taken from the verified JWT — a partner physically cannot see another partner's deliveries, and there is no query parameter that widens the scope.
The delivery guarantee. One final business outcome produces
one webhook. The platform recognises a repeated outcome and
updates the delivery record it already holds instead of creating
a second one, so a retried approval or a replayed job never
announces the same outcome twice. A delivery that did not reach
you is retried, reusing the same webhookId — see
PartnerWebhookDeliveryBody for what you receive.
See the Webhooks guide in the documentation for the signature scheme, the full event catalogue, and the retry policy.
Every webhook the platform sends to this partner leaves a delivery log row. This endpoint returns those rows, so the partner can see what was sent, to which url, and whether it arrived.
Scoped to the calling partner. The rows are selected by the partner id taken from the verified JWT — never from the request body or a query parameter. A partner therefore sees only its own deliveries: another partner's webhooks and the platform's internal webhooks are never included, and there is no query parameter that can widen that scope.
The partner id is the stable identity of the recipient, so the history survives a configuration change: webhooks delivered to an earlier url stay in the list after the url is changed.
Read-only. There is no action here to resend or modify a delivery.
A row's responseStatus is the HTTP status the partner's
endpoint answered with (200 on success, the failing status
otherwise, null if the request never got a response).
The business outcome is in payloadSent.status
(success / failed) — e.g. a cardholder that was declined is
a delivery success with a payloadSent.status of failed.
The signing secret is never returned.
This is the read side of the partner webhooks. For how the webhooks themselves are delivered — the signature scheme, the event catalogue, and the retry policy — see the Webhooks guide in the documentation.
| page | integer >= 1 Default: 1 Example: page=1 Page number for pagination. Starts at |
| limit | integer >= 1 Default: 50 Example: limit=50 Number of audit-log or card-status-history records to return per
page. Defaults to |
| success | boolean |
| count | integer |
Array of objects (PartnerWebhookLogEntry) | |
object (Pagination) |
{- "success": true,
- "count": 0,
- "data": [
- {
- "_id": "string",
- "event": "b2b_cardholder_approved",
- "webhookUrl": "string",
- "payloadSent": {
- "status": "success",
- "type": "b2b_cardholder_approved",
- "createdAt": "2026-01-15T10:30:00.000Z",
- "webhookId": "6adf2b5bfe545da555d81245",
- "cardholderId": "6adf2243ea98a84e4bdcd73f",
- "b2bAccountId": "6a9ab39e1496d30c5d392909",
- "clientID": "RYVL-1720_5"
}, - "responseStatus": 0,
- "responseBody": { },
- "error": { },
- "createdAt": "2019-08-24T14:15:22Z",
- "updatedAt": "2019-08-24T14:15:22Z"
}
], - "pagination": {
- "page": 0,
- "limit": 0,
- "total": 0,
- "pages": 0,
- "hasNextPage": true,
- "hasPrevPage": true
}
}Returns every event type the platform can send you, with its current on/off state.
An event you have never touched is on. Events are only
delivered while the master switch (webhooks.isActive, set by
your Paynovus administrator) is also on.
Scoped to the calling partner via the verified JWT.
| success required | boolean |
| count required | integer The number of supported event types. |
required | Array of objects (PartnerWebhookEvent) |
{- "success": true,
- "count": 8,
- "data": [
- {
- "event": "b2b_account_created",
- "isActive": true
}, - {
- "event": "b2b_cardholder_approved",
- "isActive": false
}
]
}Sets the state of one or several events at once. Events you do not mention keep their current state. Repeating the same request is harmless. Returns the full event list after the change.
Switching an event off stops deliveries of that event only; the master switch and your url are unchanged.
Validation — events is required and must contain at least one
entry. Each entry needs a known event type and a real boolean
isActive; a string like "false" is rejected rather than coerced.
Unknown fields are rejected, so a misspelled property is never
silently ignored.
required | Array of objects (PartnerWebhookEvent) non-empty The events to change. Events you do not mention keep their current state. | ||||
Array (non-empty)
| |||||
| success required | boolean |
| count required | integer The number of supported event types. |
required | Array of objects (PartnerWebhookEvent) |
{- "events": [
- {
- "event": "b2b_cardholder_approved",
- "isActive": false
}, - {
- "event": "b2b_iban_linked",
- "isActive": true
}
]
}{- "success": true,
- "count": 8,
- "data": [
- {
- "event": "b2b_account_created",
- "isActive": true
}, - {
- "event": "b2b_cardholder_approved",
- "isActive": false
}
]
}Sets the secret your webhooks are bound to. Our signature on every webhook covers a SHA-256 hash of this secret, so you can verify the webhook is ours and was made for your secret.
{ "secretKey": "..." } (8-200 characters) to use your own value.secretKey and we generate a strong random secret and
return it once in this response.secretKey is the only accepted request property; unknown fields
are rejected so a misspelled secret cannot be mistaken for success.A validation failure returns 400 with the offending field and the
reason in details.
The secret is stored encrypted and is write-only: no endpoint ever returns it again, so store it when you set it. Rotation takes effect immediately for webhooks sent after this call; there is no grace period for the old secret.
| secretKey | string [ 8 .. 200 ] characters The secret your webhooks are signed with. Trimmed before it is stored. |
| success required | boolean |
| hasSecret required | boolean Always true when the call succeeds — a secret is stored either way. |
| secretKeyGenerated required | boolean Whether the platform generated the secret instead of using a supplied |
| secretKey | string Only present when |
{- "secretKey": "my-own-long-random-secret"
}{- "success": true,
- "hasSecret": true,
- "secretKeyGenerated": false
}Every webhook carries an X-Payload-Signature header: an Ed25519
signature (base64) made with a private key only the platform holds.
The signed message is sha256hex(yourSecret) + "." + rawBody, so
verifying it with the key returned here proves the webhook came from
us, is unaltered, and was made for your secret. The secret itself is
never sent. X-Payload-Key-Id tells you which key signed it, so you
can pick the right one after a rotation.
Returns 503 if signing is not configured on this environment (webhooks are not sent there either).
| success required | boolean |
| keyId required | string The id of the signing key, matching the |
| algorithm required | string Value: "ed25519" |
| publicKey required | string The public key in SPKI PEM format. |
{- "success": true,
- "keyId": "9f86d081884c7d65",
- "algorithm": "ed25519",
- "publicKey": "-----BEGIN PUBLIC KEY-----\n...\n-----END PUBLIC KEY-----\n"
}