Use global fields and skip mapping entirely
Every prebuilt integration is already mapped to PalDock’s global fields. Populate them once in your lead structure, whether leads arrive through the API or form, and the same fields feed every integration you run.
Integration overview
This prebuilt PalDock integration connects your lead flow directly to the advertiser. It handles field mapping, request delivery and response processing, so you can start sending leads without building the integration from scratch.
The integration uses PalDock’s global fields and returns standardized outcomes for reporting and routing, while preserving advertiser response details for troubleshooting.
Blueprint

{
"nodes": [
{
"id": "1-1",
"type": "startNode",
"position": {
"x": -560,
"y": 40
},
"data": {
"formData": {
"active": true,
"title": "",
"subtitle": "",
"flow": "post",
"beType": "integration"
}
}
},
{
"id": "1-2",
"type": "modifyFieldNode",
"position": {
"x": -360,
"y": 40
},
"data": {
"formData": {
"active": true,
"title": "Transform data",
"subtitle": "",
"data": [
{
"fieldName": "{data_income_type}",
"fields": [
{
"source": "{data_income_type}",
"operator": "equals",
"value": "full-time",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "EMPLOYED"
},
{
"source": "{data_income_type}",
"operator": "equals",
"value": "self-employed",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "SELF_EMPLOYED"
},
{
"source": "{data_income_type}",
"operator": "equals",
"value": "parental",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "MATERNITY_LEAVE"
},
{
"source": "{data_income_type}",
"operator": "equals",
"value": "pension",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "PENSION"
},
{
"source": "{data_income_type}",
"operator": "equals",
"value": "unemployed",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "OTHER"
},
{
"source": "{data_income_type}",
"operator": "equals",
"value": "other",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "OTHER"
},
{
"source": "{data_income_type}",
"operator": "regex_not_match",
"value": "^(full-time|self-employed|parental|pension|unemployed|other)$",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "OTHER"
}
]
},
{
"fieldName": "{data_employer}",
"fields": [
{
"source": "{data_employer}",
"operator": "is_empty",
"value": "",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "nevyplněno"
}
]
},
{
"fieldName": "{data_contact_zip}",
"fields": [
{
"source": "{data_contact_zip}",
"operator": "is_empty",
"value": "",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "{data_zip}"
}
]
},
{
"fieldName": "{data_contact_city}",
"fields": [
{
"source": "{data_contact_city}",
"operator": "is_empty",
"value": "",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "{data_city}"
}
]
},
{
"fieldName": "{data_contact_street}",
"fields": [
{
"source": "{data_contact_street}",
"operator": "is_empty",
"value": "",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "{data_street}"
}
]
},
{
"fieldName": "{data_contact_house_number}",
"fields": [
{
"source": "{data_contact_house_number}",
"operator": "is_empty",
"value": "",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "{data_house_number}"
}
]
},
{
"fieldName": "{data_requested_amount}",
"fields": [
{
"source": "{data_requested_amount}",
"operator": "is_greater_than",
"value": "40000",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "40000"
}
]
}
]
}
}
},
{
"id": "1-3",
"type": "httpNode",
"position": {
"x": -140,
"y": 40
},
"data": {
"formData": {
"active": true,
"title": "Post",
"subtitle": "",
"method": "POST",
"endpoint": "{endpoint}/webapi/v1/loan/register",
"timeout": 30,
"format": null,
"parser": "json",
"notsend": null,
"convert_data": null,
"headers": [
{
"key": "Content-Type",
"value": "application/json"
},
{
"key": "Authorization",
"value": "{token}"
}
],
"query": [],
"body": [
{
"key": "client.city",
"value": "{data_city}"
},
{
"key": "client.email",
"value": "{data_email}"
},
{
"key": "client.phone",
"value": "{data_cell_phone}"
},
{
"key": "loan.loan_sum",
"value": "{data_requested_amount}"
},
{
"key": "client.address",
"value": "{data_street}"
},
{
"key": "client.employer",
"value": "{data_employer}"
},
{
"key": "client.password",
"value": "{token}"
},
{
"key": "client.last_name",
"value": "{data_last_name}"
},
{
"key": "client.origin_ip",
"value": "{ip_address}"
},
{
"key": "loan.loan_period",
"value": "{data_period}"
},
{
"key": "client.first_name",
"value": "{data_first_name}"
},
{
"key": "client.income_type",
"value": "{data_income_type}"
},
{
"key": "client.neto_income",
"value": "{data_monthly_income}"
},
{
"key": "client.personal_id",
"value": "{data_nin}"
},
{
"key": "client.bank_account",
"value": "{data_account_number}"
},
{
"key": "client.cz_bank_code",
"value": "{data_bank_code}"
},
{
"key": "client.house_number",
"value": "{data_house_number}"
},
{
"key": "client.mailing_city",
"value": "{data_contact_city}"
},
{
"key": "client.postal_index",
"value": "{data_zip}"
},
{
"key": "client.id_card_number",
"value": "{data_identity_card_number}"
},
{
"key": "client.mailing_address",
"value": "{data_contact_street}"
},
{
"key": "client.mailing_house_number",
"value": "{data_contact_house_number}"
},
{
"key": "client.mailing_postal_index",
"value": "{data_contact_zip}"
},
{
"key": "client.password_confirmation",
"value": "{token}"
},
{
"key": "client.cz_bank_account_prefix",
"value": "000000"
}
],
"signature": null,
"insecure": null
}
}
},
{
"id": "1-4",
"type": "setNode",
"position": {
"x": 100,
"y": 40
},
"data": {
"formData": {
"active": true,
"title": "Store response",
"subtitle": "",
"fields": [
{
"key": "{redirect_url}",
"value": "{parsedBody.redirect_uri}"
},
{
"key": "{external_id}",
"value": "{parsedBody.customer_number}"
}
]
}
}
},
{
"id": "1-6",
"type": "endNode",
"position": {
"x": 320,
"y": 40
},
"data": {
"formData": {
"active": true,
"title": "Success",
"subtitle": "",
"success": "success"
}
}
},
{
"id": "1-5",
"type": "modifyFieldNode",
"position": {
"x": 100,
"y": 220
},
"data": {
"formData": {
"active": true,
"title": "Reject reason · Post",
"subtitle": "",
"data": [
{
"fieldName": "{reason}",
"fields": [
{
"source": "{parsedBody.substate}",
"operator": "always",
"value": "",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "Unspecified"
},
{
"source": "{parsedBody.substate}",
"operator": "contains",
"value": "already registered",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "Duplicate"
},
{
"source": "{parsedBody.substate}",
"operator": "contains",
"value": "same email",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "Duplicate"
},
{
"source": "{parsedBody.substate}",
"operator": "contains",
"value": "již zaregistrován",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "Duplicate"
},
{
"source": "{parsedBody.substate}",
"operator": "contains",
"value": "execution report",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "Poor Credit"
},
{
"source": "{parsedBody.substate}",
"operator": "contains",
"value": "age lower",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "Age"
},
{
"source": "{parsedBody.substate}",
"operator": "contains",
"value": "not registered bank",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "Invalid Data"
},
{
"source": "{parsedBody.substate}",
"operator": "contains",
"value": "není správné",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "Invalid Data"
},
{
"source": "{parsedBody.substate}",
"operator": "contains",
"value": "A26",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "Not Eligible"
},
{
"source": "{parsedBody.substate}",
"operator": "contains",
"value": "A27",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "Not Eligible"
},
{
"source": "{parsedBody.substate}",
"operator": "contains",
"value": "income lower than limit",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "Low Income"
},
{
"source": "{parsedBody.substate.errors.0.message}",
"operator": "contains",
"value": "již zaregistrován",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "Duplicate"
},
{
"source": "{parsedBody.substate.errors.0.message}",
"operator": "contains",
"value": "není správné",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "Invalid Data"
}
]
},
{
"fieldName": "{reason_detail}",
"fields": [
{
"source": "{status}",
"operator": "always",
"value": "",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "http {status}: {parsedBody.substate}"
},
{
"source": "{parsedBody.substate.errors.0.message}",
"operator": "is_not_empty",
"value": "",
"value2": "",
"modification": "replace",
"pattern": "",
"output": "{parsedBody.substate.errors.0.message}"
}
]
}
]
}
}
},
{
"id": "1-7",
"type": "endNode",
"position": {
"x": 320,
"y": 220
},
"data": {
"formData": {
"active": true,
"title": "Rejected",
"subtitle": "",
"success": "failed"
}
}
}
],
"edges": [
{
"id": "edge-1-1-1-2",
"source": "1-1",
"target": "1-2",
"type": "customEdge",
"data": {
"active": true,
"title": "",
"subtitle": "",
"conditions": []
}
},
{
"id": "edge-1-2-1-3",
"source": "1-2",
"target": "1-3",
"type": "customEdge",
"data": {
"active": true,
"title": "",
"subtitle": "",
"conditions": []
}
},
{
"id": "edge-1-3-1-4",
"source": "1-3",
"target": "1-4",
"type": "customEdge",
"data": {
"active": true,
"title": "Accepted",
"subtitle": "",
"conditions": [
{
"value": "{parsedBody.accepted}",
"operator": "contains",
"output": "true",
"output2": ""
},
{
"value": "{status}",
"operator": "equals",
"output": "201",
"output2": ""
}
]
}
},
{
"id": "edge-1-3-1-5",
"source": "1-3",
"target": "1-5",
"type": "customEdge",
"data": {
"active": true,
"title": "Rejected",
"subtitle": "",
"conditions": [
{
"value": "{status}",
"operator": "equals",
"output": "200",
"output2": ""
},
{
"value": "{parsedBody.accepted}",
"operator": "equals",
"output": "false",
"output2": ""
}
]
}
},
{
"id": "edge-1-4-1-6",
"source": "1-4",
"target": "1-6",
"type": "customEdge",
"data": {
"active": true,
"title": "",
"subtitle": "",
"conditions": []
}
},
{
"id": "edge-1-5-1-7",
"source": "1-5",
"target": "1-7",
"type": "customEdge",
"data": {
"active": true,
"title": "",
"subtitle": "",
"conditions": []
}
}
]
}How it works
- Copy the blueprint and paste it in your PalDock workspace– Create a new integration in your workspace and paste the blueprint. Every field arrives prefilled.
- Enter your credentials – Paste the secrets you received from advertiser and set your Pingtree
- Send a test lead – Verify the response, then switch the channel live.
FAQ
Do I need my own contract with this advertiser?
Yes. PalDock delivers leads on your behalf, so the commercial agreement and API credentials come from the advertiser directly.
What happens to rejected leads?
The advertiser returns its decision in the delivery response. PalDock reads it and moves rejected leads to the next buyer in your pingtree automatically, so a rejection does not need to end the lead’s journey.
Can I change the field mapping?
Yes, but we do not recommend it. Blueprints are already mapped to PalDock’s global fields. If you use local fields, you need to remap each integration separately.
How long does setup take?
Few clicks, if you already have credentials. The blueprint arrives prefilled and mapped to PalDock’s global fields, so if your lead structure uses them, there is nothing to map. If you use local fields, you map them once.
What the integration does
Start sending leads in 3 clicks
Copy the prebuilt blueprint, add your credentials and start sending leads. No coding, no integration work.
Real-time lead delivery
Send leads to the advertiser instantly as they arrive, without exports, batches or manual processing.
No field mapping headache
PalDock global fields work across all prebuilt integrations. Map your lead data once and reuse it everywhere.
Know exactly why leads fail
Get standardized rejection reasons for reporting and advertiser’s response for the full context and troubleshooting.
API & integration details
Also trades as VivaCredit. One call registers the customer and decides. There is no ping.
The response is unusual and worth understanding before anything else: acceptance and rejection have different body shapes and different status codes, and the rejection reason arrives in a field called substate that is sometimes a string and sometimes an object.
What will be needed from advertiser
| Key | Purpose |
|---|---|
endpoint | Base API URL. |
token | Authorization token. |
Flows
Post, POST /webapi/v1/loan/register. Registers and decides.
Calls
POST {endpoint}/webapi/v1/loan/register
Authorization: {token}
Content-Type: application/json
format: application/json
The token goes in Authorization with no scheme prefix, no Bearer, no Token.
Request fields
Dotted paths for nesting, client and loan.
| Field | Required | Value |
|---|---|---|
client.first_name | yes | {g_name_first} |
client.last_name | yes | {g_name_last} |
client.email | yes | {g_email}, must be unique |
client.phone | yes | {g_phone}, nine digits |
client.personal_id | yes | {g_id_national_number}, must be unique and valid |
client.id_card_number | yes | {g_id_card_number} |
client.income_type | yes | {g_fin_type}, see enums |
client.neto_income | yes | {g_fin_income} |
client.employer | yes | {g_employer_name} |
client.address | yes | {g_address_street} |
client.house_number | yes | {g_address_street_number} |
client.city | yes | {g_address_city} |
client.postal_index | yes | {g_address_zip} |
client.mailing_address | yes | {g_address_contact_street} |
client.mailing_house_number | yes | {g_address_contact_street_number} |
client.mailing_city | yes | {g_address_contact_city} |
client.mailing_postal_index | yes | {g_address_contact_zip} |
client.bank_account | yes | {g_bank_account_number}, must be unique |
client.cz_bank_code | yes | {g_bank_account_code} |
client.cz_bank_account_prefix | yes | {g_bank_account_prefix}, 000000 when there is none |
client.password | yes | a fixed value the integration controls |
client.password_confirmation | yes | the same fixed value |
client.origin_ip | yes | {ip_address} |
loan.loan_sum | yes | {g_amount}, capped at 40 000 |
loan.loan_period | yes | {g_period} |
client.next_payday | no | {g_period_end} as yyyy-MM-dd, defaults to today |
The mailing address fields are mandatory even when they are the same as the permanent one. Fill them from the permanent address when the form leaves them empty rather than sending blanks, an empty required field is a rejected request here.
employer is mandatory too, including for people who have no employer. Fill it with a placeholder rather than dropping it.
password and password_confirmation create the customer’s account. Any stable value the integration controls works.
On capping the amount
Where a request exceeds the advertiser’s maximum, send the maximum rather than the requested figure, but agree it with them first. Translating a higher request down is right only when they would otherwise reject the lead outright. Where they would have made a smaller offer on their own, send what the applicant actually asked for and let them answer.
This is the one place the general rule bends: amount, term and product are the request itself, so they are normally passed through untouched.
Enums
client.income_type: EMPLOYED, SELF_EMPLOYED, PENSION, MATERNITY_LEAVE, OTHER. There is no unemployed option, map it to OTHER.
Outcomes
substate has two shapes. Usually it is a plain string. For validation failures it is an object holding an errors list, and the useful text sits at {parsedBody.substate.errors.0.message}, with the index, or it does not resolve at all.
Set {reason_detail} from {body} on an unconditional row so both shapes are covered, then add the indexed path as an extra conditional row on top.
| Recognised by | HTTP | Meaning | Reject reason | Frequency |
|---|---|---|---|---|
accepted: true + redirect_uri | 201 | Accepted | , | occasional |
substate ~ already registered | 200 | Already a customer | Duplicate | common |
substate ~ customer with same email | 200 | E-mail on file | Duplicate | occasional |
substate ~ [A26] | 200 | Knockout criterion | Not Eligible | occasional |
substate ~ [A27 - local authorities check] | 200 | Knockout criterion | Not Eligible | occasional |
substate ~ age lower than limit | 200 | Below the age limit | Age | occasional |
substate ~ execution report | 200 | Enforcement on record | Debt Collection | occasional |
substate ~ income lower than limit | 200 | Income below threshold | Low Income | rare |
substate ~ not registered bank | 200 | Bank not supported | Invalid Data | occasional |
substate.errors[].message ~ Číslo bankovního účtu není správné | 200 | Malformed account number | Invalid Data | rare |
substate.errors[].message ~ bankovní účet je u nás již zaregistrován | 200 | Account already on file | Duplicate | rare |
substate: internal server error | 500 | Advertiser-side failure | , (technical) | rare |
substate has two shapes. Usually it is a plain string. For validation failures it is an object holding an errors list, and the useful text is at {parsedBody.substate.errors.0.message}, with the index, or it does not resolve at all.
Set {reason_detail} from {body} on an unconditional row so both shapes are covered, then add the indexed path as an extra conditional row on top.
[A26] and [A27] are the advertiser’s own knockout codes. They name a condition the lead failed that you could not have checked in advance, which is what Not Eligible is for. Everything that merely says no goes to Unspecified instead.
Reject reasons come from the standard list. See Reject reason for what each one means and when to use it.
Branching
Accepted:
{status} equals 201
{parsedBody.accepted} contains true
Rejected, a business answer under 200:
{status} equals 200
{parsedBody.accepted} equals false
500 and 503 carry no business result and get no branch.
Stored values
| Parameter | Source |
|---|---|
{external_id} | {parsedBody.customer_number} |
{redirect_url} | {parsedBody.redirect_uri} |
Advertiser APIs change without warning
When they do, leads stop being delivered, often before anyone notices. PalDock gives you delivery logs and alerts so you can catch it early. With Managed Integrations, we watch the connection and fix it for you.
