{"openapi":"3.0.3","info":{"title":"Plus1IT — HubSolution Integration","description":"Hubsolution is a product that enables partners to collect consumer applications, which Adtraction standardizes and forwards to the brand (Plus1IT). A successful submission is a complete lead — no consumer-side redirect is needed.\n\n## How Hubsolution Works\n\n1. The consumer completes an application form on the partner's site, which is then sent to Adtraction (our Hubsolution).\n2. Adtraction standardizes the application data and forwards it to the brand.\n3. Brands or Adtraction accept or reject the application based on the hard rules set by the brand. An accepted application is a complete lead — there is no consumer-side redirect or follow-up step.\n4. A conversion is generated when the brand accepts the lead (or, in some cases, when the lead is received by the brand).\n\n## Program Information\n\n- **Program link:** [secure.adtraction.com/partner/program.htm?apid=2106439085](https://secure.adtraction.com/partner/program.htm?apid=2106439085)\n- **Support:** [hubsupport@adtraction.com](mailto:hubsupport@adtraction.com)\n\n## Authentication\n\nNo authentication headers are required. All traffic must use HTTPS (port 443).\n\n## Flow\n\n```\n1. GET  /specific/2106439085/fields   ← discover required fields\n2. POST /specific/2106439085          ← submit application\n```\n\n## Date format\n\nRequest fields that carry a date only (e.g. `main_applicant.birth_date`) use `YYYY-MM-DD`. Response timestamps from Adtraction are in Copenhagen time (CET/CEST) using `YYYY-MM-DD HH:MM:SS` — e.g. `2000-01-31 00:00:00`.\n","version":"1.0.0"},"x-hubsolution":{"programId":"2106439085","programName":"Plus1IT","countryCode":"IT","guide":"## Implementation Checklist\n\n1. **Fetch required fields** — call `GET /specific/2106439085/fields` first; it marks each field `true` (mandatory) or `false` (optional). Build your form from the live response, as requirements can change.\n2. **Use your own channel ID** — replace the example `channel_id` with the one assigned to your account (find it in your Adtraction account or ask hubsupport@adtraction.com). The wrong ID misroutes or fails to attribute the lead.\n3. **Sandbox first** — send `sandbox: 1` while testing (no real lead is created) and `sandbox: 0` only in production.\n4. **Real user agent & IP** — forward the consumer's own `User-Agent` and originating IP (e.g. from `X-Forwarded-For`), captured server-side. Never send your server's values, or fraud checks and attribution break.\n5. **Include every mandatory field** — a missing one returns `Missing data: <field>`. Cross-check against the fields endpoint before submitting.\n6. **Validate client-side** — check formats and the **Field constraints** on the submit endpoint before sending, to cut round-trips and rejections.\n7. **Handle the response on `valid`** — treat `success: true` + `valid: true` as a complete lead (see Responses & errors below).\n8. **Go live with your account manager** — once sandbox is verified, coordinate a production check (`sandbox: 0`) before switching fully live.\n\n## Response Handling & Error Responses\n\nEvery response is JSON with two booleans, `success` and `valid`. **Branch on `valid`, not the HTTP status code:** `valid: true` means the brand accepted the application; `valid: false` means it was not accepted — a validation failure, duplicate, brand rejection, or internal error — with a human-readable `message` and sometimes a `status` of `rejected` or `failed`. A brand rejection is a non-accepted lead, not an error to retry.\n\n| Message | Meaning & suggested action |\n| --- | --- |\n| `Missing program_id` | The request did not target a program. Check the URL path includes the program ID. |\n| `Incorrect program_id` | The program ID is malformed. Verify it matches the value from your Adtraction account. |\n| `No matching program` | No active program was found for that ID. Confirm the program is live and the ID is correct. |\n| `Missing channel_id` | No channel ID was supplied. Include your partner-specific channel_id in the request. |\n| `Invalid channel_id: must be a valid integer` | The channel_id was not a valid integer. Send the numeric channel ID assigned to your account. |\n| `Missing channel_id or insufficient program access` | The channel ID is missing or not authorised for this program. Verify your channel has access; contact support if it should. |\n| `Missing data: <field>` | A mandatory field was not provided (one message per missing field). Fetch the fields endpoint and include all mandatory fields. |\n| `Consent not granted` | Required consent was not given. Capture the consumer consent before submitting. |\n| `Duplicate User` | A matching application already exists for this consumer. Do not resubmit the same lead. |\n| `Budget check failed` | The program has no remaining budget for this lead. Retry later or contact your account manager. |\n| `Failed to log response / Something went wrong` | An unexpected internal error occurred. Safe to retry; contact support if it persists. |"},"servers":[{"url":"https://hubsolution.adtraction.com","description":"HubSolution"}],"paths":{"/specific/2106439085/fields":{"get":{"operationId":"getFields","summary":"Get required fields","description":"Returns the required (and optional) fields for this integration. Use this to build your application form. Each value is a boolean: `true` = mandatory, `false` = optional.","tags":["Fields"],"responses":{"200":{"description":"Required fields for this integration","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FieldsResponse"},"example":{"required_fields":{"channel_id":true,"user_agent":true,"ip":true,"main_applicant":{"first_name":true,"last_name":true,"email_address":true,"phone_number":true,"ssn":true,"monthly_income":true,"accomodation_monthly_cost":true,"birth_date":true,"employer_name":false,"employment_type":false,"accomodation_type":false,"marital_status":false,"children_under_18":false},"new_loan_amount":true,"duration":false,"purpose":false}}}}}}}},"/specific/2106439085":{"post":{"operationId":"submitApplication","summary":"Submit an application to Plus1IT","description":"Submit a consumer application. The request is validated before being forwarded to the brand.\n\n**Field constraints:**\n\n- `new_loan_amount` must be ≥ 2000 — *\"new_loan_amount must be between 2.000€ and 50.000€\"*\n- `new_loan_amount` must be ≤ 50000 — *\"new_loan_amount must be between 2.000€ and 50.000€\"*\n- `main_applicant.monthly_income` must be ≥ 1500 — *\"monthly_income must be at least 1.500€ for IT\"*\n- `main_applicant.monthly_income` must be ≤ 500000\n- `main_applicant.accomodation_monthly_cost` must be ≤ 100000\n- `main_applicant.birth_date`: applicant must be at least 21 years old — *\"Applicant must be at least 21 years old\"*\n- `main_applicant.ssn` must match pattern `^[A-Z]{6}[0-9LMNPQRSTUV]{2}[ABCDEHLMPRST][0-9LMNPQRSTUV]{2}[A-Z][0-9LMNPQRSTUV]{3}[A-Z]$` — *\"ssn must be an Italian codice fiscale (16 characters)\"*\n- `duration` must be ≥ 60 — *\"duration must be between 60 and 144 months\"*\n- `duration` must be ≤ 144 — *\"duration must be between 60 and 144 months\"*\n- `main_applicant.children_under_18` must be ≤ 6","tags":["Application"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Application"},"example":{"channel_id":"123456","user_agent":"Mozilla/5.0 ...","ip":"192.168.0.1","sandbox":1,"new_loan_amount":50000,"duration":36,"purpose":"CONSUMPTION","main_applicant":{"first_name":"Test","last_name":"Rossi","email_address":"test@example.com","phone_number":"+393401234567","ssn":"RSSMRA90A15H501K","monthly_income":2000,"accomodation_monthly_cost":400,"birth_date":"1990-01-15","employer_name":"Test SRL","employment_type":"PERMANENT","accomodation_type":"RENTAL","marital_status":"SINGLE","children_under_18":0}}}}},"responses":{"200":{"description":"Application accepted (or rejected with `valid: false`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SuccessResponse"},"example":{"success":true,"valid":true,"integration":"Plus1IT","tracking_id":"abc123...","order_id":"550e8400-e29b-41d4-a716-446655440000"}}}},"400":{"description":"Validation failure","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"},"example":{"success":false,"valid":false,"message":"Validation error message","tracking_id":"abc123..."}}}},"500":{"description":"Internal error contacting the partner backend","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"components":{"schemas":{"Application":{"type":"object","required":["channel_id","user_agent","ip","new_loan_amount","main_applicant"],"properties":{"channel_id":{"type":"string","description":"Your unique Adtraction channel ID — partner-specific. Use the channel ID assigned to your account (not the example value); sending the wrong channel ID misroutes or fails to attribute the lead. Find it in your Adtraction partner account (see Program Information in the description) or ask your account manager / hubsupport@adtraction.com.","example":"123456"},"user_agent":{"type":"string","description":"Consumer browser user agent","example":"Mozilla/5.0 ..."},"ip":{"type":"string","description":"Consumer IP address (required if the remote IP does not match the actual user)","example":"192.168.0.1"},"new_loan_amount":{"type":"number","description":"Requested loan amount (portion not used to settle existing loans)","example":50000},"duration":{"type":"number","description":"Loan term in months. Accepted values may vary per integration","example":36},"purpose":{"type":"string","description":"Purpose of the loan","example":"CONSUMPTION","enum":["NEW","GATHER","RENOVATE","CONSUMPTION","VEHICLE","HEALTH_CARE","OTHER","STUDIES_OR_TRAINING","HOUSEHOLD_EQUIPMENT","PERSONAL_EQUIPMENT"]},"sandbox":{"type":"integer","description":"`1` for sandbox, `0` for production","example":1,"enum":[0,1]},"main_applicant":{"$ref":"#/components/schemas/MainApplicant"}}},"MainApplicant":{"type":"object","required":["first_name","last_name","email_address","phone_number","ssn","monthly_income","accomodation_monthly_cost","birth_date"],"properties":{"first_name":{"type":"string","description":"First name","example":"Test"},"last_name":{"type":"string","description":"Last name","example":"Rossi"},"email_address":{"type":"string","description":"Valid email address","example":"test@example.com"},"phone_number":{"type":"string","description":"Cellphone number (E.164 preferred, e.g. `+46701234567`)","example":"+393401234567"},"ssn":{"type":"string","description":"National ID / social security number (e.g. Swedish personnummer in 12-digit format `ÅÅÅÅMMDDXXXX`)","example":"RSSMRA90A15H501K"},"monthly_income":{"type":"number","description":"Monthly gross income","example":2000},"accomodation_monthly_cost":{"type":"number","description":"Monthly housing cost (mortgage or rent)","example":400},"birth_date":{"type":"string","description":"Birth date (YYYY-MM-DD)","example":"1990-01-15"},"employer_name":{"type":"string","description":"Employer name (if employed)","example":"Test SRL"},"employment_type":{"type":"string","description":"Employment type","example":"PERMANENT","enum":["PERMANENT","PART_TIME","NEEDS","TEMPORARY","PRIVATE","OWNS_COMPANY","RETIRED","EARLY_RETIREMENT","PROBATION","STUDENT","HOUSEWIFE","UNEMPLOYED"]},"accomodation_type":{"type":"string","description":"Accommodation type","example":"RENTAL","enum":["HOUSE","TENANT","TENANCY","INHERENT","OWNER_WITH_MORTAGE","OWNER_WITHOUT_MORTAGE","RENTAL","COOWNER","COSTED_BY_COMPANY"]},"marital_status":{"type":"string","description":"Marital status","example":"SINGLE","enum":["SINGLE","MARRIED","DIVORCED","WIDOWED","DOMESTIC"]},"children_under_18":{"type":"integer","description":"Children under 18 in legal care (0–20)","example":0}}},"FieldsResponse":{"type":"object","properties":{"required_fields":{"type":"object","description":"For each field, `true` = mandatory (must be included in your request) and `false` = optional (accepted if present). `main_applicant` is a nested object of the same booleans.","additionalProperties":true}}},"SuccessResponse":{"type":"object","properties":{"success":{"type":"boolean"},"valid":{"type":"boolean","description":"`true` if the brand accepted the application"},"integration":{"type":"string","example":"Plus1IT"},"tracking_id":{"type":"string","description":"HubSolution tracking ID for this application"},"order_id":{"type":"string","description":"Unique identifier for the accepted application"}}},"ErrorResponse":{"type":"object","properties":{"success":{"type":"boolean","example":false},"valid":{"type":"boolean","example":false},"message":{"type":"string","description":"Human-readable error message"},"status":{"type":"string","enum":["rejected","failed"],"description":"Set when a valid request was not accepted by the brand: `rejected` (brand declined) or `failed` (downstream/internal error)"},"tracking_id":{"type":"string"}}}}},"tags":[{"name":"Fields","description":"Discover required fields for this integration"},{"name":"Application","description":"Submit applications to Plus1IT"}]}