Skip to content

Joint Application Flow

This guide demonstrates the flow for processing a joint application with both a primary applicant and co-applicant.

A joint application involves two applicants whose debts can be combined for eligibility evaluation. The flow is similar to the single applicant flow but includes additional steps for the co-applicant.

  1. Authenticate - Obtain an access token from Azure AD 2. Pull Primary Credit Report - Retrieve the primary applicant’s credit data 3. Pull Co-Applicant Credit Report - Retrieve the co-applicant’s credit data 4. Check Joint Eligibility - Evaluate combined eligibility with applicationType: "JOINT" 5. Update Eligibility (Optional) - Modify applicant info or debt selections 6. Generate Offers - Create payment plan options for the combined debts 7. Create Offer - Save the selected payment plan 8. Create Enrollment - Create the client file in the CRM with co-applicant info 9. Check Enrollment Status - Monitor enrollment progress

Step 1: Authenticate

Obtain an access token using OAuth 2.0 client credentials flow. The token is used as a Bearer token for all subsequent API requests.

Key Differences from Single Applicant

Application Type

When checking eligibility for a joint application, set applicationType to "JOINT":

mutation CheckApplicantEligibility(
$applicationType: ApplicationTypeInput!
$input: UwResultCheckInput!
) {
checkApplicantEligibility(applicationType: $applicationType, input: $input) {
data {
id
revision
jointUwResult {
id
primaryApplicantUwResult {
id
revision
}
coApplicantUwResult {
id
revision
}
debts {
id
applicantId
coApplicantId
isSelected
coApplicantIsSelected
eligibilityStatus
}
}
}
errors {
message
}
}
}

Input Structure

The joint application input includes both primaryReportId and coCreditReportId:

{
"applicationType": "JOINT",
"input": {
"primaryReportId": "{{creditReportId}}",
"coCreditReportId": "{{coCreditReportId}}",
"applicantContactInfo": {
"firstName": "JOHN",
"lastName": "DOE",
"applicantState": "CA",
"ssn": "123456789",
"dob": "1980-01-15",
"isMarriedToCoApplicant": true
},
"coApplicantContactInfo": {
"firstName": "JANE",
"lastName": "DOE",
"applicantState": "CA",
"ssn": "987654321",
"dob": "1982-05-20",
"isMarriedToCoApplicant": true
}
}
}

Debt Ownership

In a joint application, debts can belong to:

  • Primary applicant only (applicantId set)
  • Co-applicant only (coApplicantId set)
  • Both applicants (joint debt)

The response includes:

  • isSelected: Whether the debt is selected for the primary applicant
  • coApplicantIsSelected: Whether the debt is selected for the co-applicant

Step 7: Create Offer

After selecting a payment plan from the offers, use createOffer to save the selected plan. This converts the transient plan into a persistent offer and returns an offerId (also referred to as ogId) that you’ll use for enrollment.

Endpoint: https://debt-core-api-sandbox.alleviate.com/og-service/graphql

mutation CreateOffer($input: OffersInput!) {
createOffer(input: $input) {
data {
id
uwResultId
uwResultRevision
frequency
frequencyInterval
firstPaymentDate
paymentTerm
maxPaymentTerm
enrolledDebt
enrollmentPlanId
enrollmentPlanName
serviceFee
estimatedSettlementFee
totals {
fee1
fee2
fee3
fee4
fee5
fee6
fee7
savings
totalPayment
}
payments {
fee1
fee2
fee3
fee4
fee5
fee6
fee7
paymentDate
paymentNumber
savings
totalPayment
}
forthRequestParameters {
epFee1Amount
fee2Amount
fee2Ends
epFee2Monthly
epFee3Amount
epFee3Monthly
epFee4Monthly
epFee4Amount
epFee5Monthly
epFee5Amount
firstPaymentDate
recurringStartDate
epFrequency
epFreqInterval
debt
enrollmentPlan
maxPaymentTerm
estSettlement
}
compTemplateId
}
errors {
message
}
}
}

Variables:

{
"input": {
"firstPaymentDate": "2025/04/12",
"depositFrequency": "M",
"depositIntervals": "12",
"uwResultId": "{{uwResultId}}",
"revision": 1,
"includeSentryFee": true,
"paymentTerm": "60"
}
}

Step 8: Create Enrollment

After creating an offer, use createEnrollment to create the client file in the destination CRM. For joint applications, the co-applicant’s PII is sourced from UW data — only optional fields like budgetFields, customFields, and notes are passed in the contact input.

Endpoint: https://debt-core-api-sandbox.alleviate.com/enrollment-service/graphql

mutation CreateEnrollment($input: CreateEnrollmentInput!) {
createEnrollment(input: $input) {
data {
enrollmentId
}
errors {
message
}
}
}

Variables:

{
"input": {
"ogId": "{{offerId}}",
"leadId": "11223344",
"contact": {
"language": "1",
"budgetFields": [
{
"fieldId": "monthlyIncome",
"value": "5000.00"
},
{
"fieldId": "monthlyExpenses",
"value": "3500.00"
}
],
"customFields": [
{
"fieldId": "referralSource",
"value": "Website"
}
],
"notes": [
{
"content": "Client prefers communication via email"
}
]
}
}
}

Step 9: Check Enrollment Status

Use the enrollmentStatus query to monitor the progress of enrollment creation. After calling createEnrollment, it returns an enrollmentId that you can use to track the status of individual enrollment steps.

Endpoint: https://debt-core-api-sandbox.alleviate.com/enrollment-service/graphql

query EnrollmentStatus($enrollmentId: String!) {
enrollmentStatus(enrollmentId: $enrollmentId) {
data {
qaCall
createContact
createNotes
createDebts
createBudget
createBankAccount
createDocuments
}
errors {
message
}
}
}

Variables:

{
"enrollmentId": "{{enrollmentId}}"
}

Status Values

Each step in the response will have one of the following statuses:

  • PENDING - Step has not started yet
  • IN_PROGRESS - Step is currently being processed
  • COMPLETED - Step finished successfully
  • FAILED - Step encountered an error

Flow Diagram

┌──────────────────────────────────────────────────────────────────────────────┐
│ Joint Application Flow │
├──────────────────────────────────────────────────────────────────────────────┤
│ │
│ 1. Authenticate (Azure AD) │
│ └─► Returns: access_token │
│ │ │
│ ▼ │
│ 2. pullCreditReport (Primary Applicant) │
│ └─► Returns: creditReportId │
│ │ │
│ ▼ │
│ 3. pullCreditReport (Co-Applicant) │
│ └─► Returns: coCreditReportId │
│ │ │
│ ▼ │
│ 4. checkApplicantEligibility (applicationType: JOINT) │
│ └─► Returns: uwResultId, jointUwResult, combined debts │
│ │ │
│ ▼ │
│ 5. updateApplicantEligibility [OPTIONAL] │
│ └─► Returns: updated uwResultId, revision │
│ │ │
│ ▼ │
│ 6. offers (Offer Generation API) │
│ └─► Returns: payment plans for combined eligible debt │
│ │ │
│ ▼ │
│ 7. createOffer (Offer Generation API) │
│ └─► Returns: offerId (ogId) │
│ │ │
│ ▼ │
│ 8. createEnrollment (Enrollment API) │
│ └─► Returns: enrollmentId │
│ │ │
│ ▼ │
│ 9. enrollmentStatus (Enrollment API) │
│ └─► Returns: status of enrollment steps │
│ │
└──────────────────────────────────────────────────────────────────────────────┘

API Endpoints

APISandbox URL
Credit APIhttps://debt-core-api-sandbox.alleviate.com/credit-service/graphql
Underwriting APIhttps://debt-core-api-sandbox.alleviate.com/underwriting-service/graphql
Offer Generation APIhttps://debt-core-api-sandbox.alleviate.com/og-service/graphql
Enrollment APIhttps://debt-core-api-sandbox.alleviate.com/enrollment-service/graphql

Best Practices

  1. Pull both credit reports first - Ensure you have both creditReportId and coCreditReportId before checking eligibility
  2. Handle married applicants - Set isMarriedToCoApplicant appropriately for correct debt ownership evaluation
  3. Review joint debts - Some debts may appear on both credit reports; the system handles deduplication
  4. Validate both applicants - Ensure both applicants pass individual eligibility checks
  5. Co-applicant PII is sourced from UW data - No need to pass co-applicant contact details in the enrollment input
  6. Store intermediate IDs - Keep track of creditReportId, coCreditReportId, uwResultId, revision, offerId (ogId), and enrollmentId
  7. Monitor enrollment progress - Poll enrollmentStatus until all steps show COMPLETED